docxText.ts 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import {
  2. Paragraph,
  3. TextRun,
  4. HeadingLevel,
  5. ParagraphChild
  6. } from "docx"
  7. import { handleNodes } from "./handleNodes"
  8. const sizeMap: Record<string, number> = {
  9. h1: 36,
  10. h2: 32,
  11. h3: 28,
  12. h4: 24,
  13. h5: 22,
  14. h6: 20,
  15. p: 22
  16. }
  17. const handleText = (el: Element): Paragraph | undefined => {
  18. const tag = el.tagName.toLowerCase()
  19. // 标题段落处理
  20. if (/^h[1-6]$/.test(tag)) {
  21. const level = parseInt(tag[1])
  22. const paragraph = new Paragraph({
  23. children: [new TextRun({ text: el.textContent?.trim() ?? "", bold: true, size: sizeMap[tag] ?? 22 })],
  24. heading: (("Heading" + (level)) as (typeof HeadingLevel)[keyof typeof HeadingLevel]),
  25. spacing: { after: 200 },
  26. })
  27. return paragraph
  28. }
  29. // 段落处理
  30. if (tag === "p") {
  31. if (el.children.length === 0) {
  32. // 普通文本结构
  33. const paragraph = new Paragraph({
  34. children: [new TextRun({ text: el.textContent?.trim() ?? "" })],
  35. spacing: { after: 200 },
  36. })
  37. return paragraph
  38. } else {
  39. // 复杂文本,交给handleNodes统一处理
  40. return handleNodes(el.childNodes)
  41. }
  42. }
  43. }
  44. /**
  45. *
  46. * @param el
  47. * @returns undefined 匹配失败
  48. * @returns ParagraphChild 段落子部件
  49. * ParagraphChild介绍
  50. * ParagraphChild = TextRun | ImageRun | SymbolRun | Bookmark | PageBreak | ColumnBreak | SequentialIdentifier | FootnoteReferenceRun | InternalHyperlink | ExternalHyperlink | InsertedTextRun | DeletedTextRun | Math | SimpleField | SimpleMailMergeField | Comments | Comment | CommentRangeStart | CommentRangeEnd | CommentReference | CheckBox
  51. * TextRun
  52. * 表示一段文本,支持字体、加粗、颜色、高亮、上标/下标、大小、斜体等样式。是最常见的段落子元素。
  53. * ImageRun
  54. * 插入图像,可以是 Buffer、base64 或路径。支持控制大小、浮动、对齐方式等。
  55. * SymbolRun
  56. * 插入符号,例如特殊字符(☑、★等)。
  57. * Bookmark
  58. * 插入书签,供跳转或引用使用。
  59. * PageBreak
  60. * 插入分页符。
  61. * ColumnBreak
  62. * 插入分栏符,用于多栏布局的换栏操作。
  63. * SequentialIdentifier
  64. * 插入一个自动编号序列,如编号字段。
  65. * FootnoteReferenceRun
  66. * 插入脚注引用,链接到底部脚注。
  67. * InternalHyperlink
  68. * 插入指向文档内部书签的链接(例如跳转到某一章节)。
  69. * ExternalHyperlink
  70. * 插入外部链接,例如网页 URL。
  71. * InsertedTextRun/DeletedTextRun
  72. * 表示插入或删除的文字(用于显示修改痕迹/修订内容)。
  73. * Math
  74. * 表示数学公式,内部基于 Office MathML (OMML) 或 MathType 结构。用来插入数学表达式。
  75. * SimpleField/SimpleMailMergeField
  76. * 插入 Word 字段(如页码、日期等)或邮件合并字段。
  77. * CommentRangeStart/CommentRangeEnd
  78. * 注释范围的起始和结束标记,用于将某一段文字标记为注释内容。
  79. * CommentReference/Comments/Comment
  80. * 插入注释引用或注释本体内容,供审阅使用。
  81. * CheckBox
  82. * 插入复选框,可设置是否勾选。
  83. */
  84. const handleEmbeddedText = (el: Element): ParagraphChild | undefined => {
  85. const tag = el.tagName.toLowerCase()
  86. if (tag === 'br') {
  87. return new TextRun({ break: 1 }) // 添加换行
  88. }
  89. if (tag === 'strong') {
  90. let textRun: TextRun
  91. if (el.children.length === 0) {
  92. // 普通文本结构
  93. new TextRun({ text: el.textContent?.trim() ?? "", bold: true})
  94. return paragraph
  95. } else {
  96. // 复杂文本,交给handleNodes统一处理
  97. return handleNodes(el.childNodes)
  98. }
  99. }
  100. }
  101. export default {
  102. handleText,
  103. handleEmbeddedText,
  104. config: {} // 无配置
  105. }