docxList.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import {
  2. Paragraph,
  3. INumberingOptions,
  4. LevelFormat,
  5. Table,
  6. } from "docx"
  7. import { handleNestElement } from "./handleElement"
  8. import { handleNodes } from "./handleNodes"
  9. const config: {numbering?: INumberingOptions} = {
  10. numbering: {
  11. config: [
  12. {
  13. reference: "bullet-numbering", // 自定义编号 ID
  14. levels: [
  15. {
  16. level: 0,
  17. format: LevelFormat.BULLET, // 无序列表用 BULLET
  18. text: "•", // 符号
  19. alignment: "left",
  20. style: {
  21. paragraph: {
  22. indent: { left: 720, hanging: 260 }
  23. }
  24. }
  25. },
  26. {
  27. level: 1,
  28. format: LevelFormat.BULLET,
  29. text: "o",
  30. alignment: "left",
  31. style: {
  32. paragraph: {
  33. indent: { left: 1440, hanging: 260 }
  34. }
  35. }
  36. },
  37. {
  38. level: 2,
  39. format: LevelFormat.BULLET,
  40. text: "▪",
  41. alignment: "left",
  42. style: {
  43. paragraph: { indent: { left: 2160, hanging: 260 } }
  44. }
  45. }
  46. ]
  47. },
  48. {
  49. reference: "ordered-numbering", // 有序列表 ID
  50. levels: [
  51. {
  52. level: 0,
  53. format: LevelFormat.DECIMAL, // 有序列表用 DECIMAL(1, 2, 3)
  54. text: "%1.",
  55. alignment: "left",
  56. style: {
  57. paragraph: {
  58. indent: { left: 720, hanging: 260 }
  59. }
  60. }
  61. },
  62. {
  63. level: 1,
  64. format: LevelFormat.LOWER_LETTER, // 二级有序列表 a,b,c
  65. text: "%2.",
  66. alignment: "left",
  67. style: {
  68. paragraph: {
  69. indent: { left: 1440, hanging: 260 }
  70. }
  71. }
  72. },
  73. {
  74. level: 2,
  75. format: LevelFormat.LOWER_ROMAN, // i, ii, iii ...
  76. text: "%3.",
  77. alignment: "left",
  78. style: {
  79. paragraph: { indent: { left: 2160, hanging: 260 } }
  80. }
  81. }
  82. ]
  83. }
  84. ]
  85. }
  86. }
  87. const handleList = async (el: Element): Promise<(Paragraph | Table)[] | undefined> => {
  88. const tag = el.tagName.toLowerCase()
  89. // 无序列表
  90. if (tag === "ul") {
  91. const paragraphList: (Paragraph | Table)[] = []
  92. for (const li of Array.from(el.querySelectorAll("li"))) {
  93. if (li.children.length === 0) {
  94. // 普通文本结构
  95. const paragraph = new Paragraph({
  96. text: li.textContent ?? "",
  97. numbering: {
  98. reference: "bullet-numbering",
  99. level: 0,
  100. },
  101. bullet: { level: 0 },
  102. spacing: { after: 100 },
  103. })
  104. paragraphList.push(paragraph)
  105. } else {
  106. // 复杂文本,交给handleNodes统一处理
  107. paragraphList.push(handleNodes(li.childNodes))
  108. }
  109. const childParagraph = await handleNestElement(li)
  110. paragraphList.push(...childParagraph)
  111. }
  112. return paragraphList
  113. }
  114. // 有序列表
  115. if (tag === "ol") {
  116. const paragraphList: (Paragraph | Table)[] = []
  117. for (const li of Array.from(el.querySelectorAll("li"))) {
  118. if (li.children.length === 0) {
  119. const paragraph = new Paragraph({
  120. text: li.textContent ?? "",
  121. numbering: {
  122. reference: "ordered-numbering",
  123. level: 0,
  124. },
  125. spacing: { after: 100 },
  126. })
  127. paragraphList.push(paragraph)
  128. } else {
  129. // 复杂文本,交给handleNodes统一处理
  130. paragraphList.push(handleNodes(li.childNodes))
  131. }
  132. const childParagraph = await handleNestElement(li)
  133. paragraphList.push(...childParagraph)
  134. }
  135. return paragraphList
  136. }
  137. }
  138. export default {
  139. handleList,
  140. config
  141. }