123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- import Color from 'color'
- import {
- IElement,
- ElementType,
- TitleLevel,
- ListStyle,
- Command
- } from '@hufe921/canvas-editor'
- import {
- Document,
- Packer,
- Paragraph,
- Header,
- Footer,
- Table,
- HeadingLevel,
- ParagraphChild,
- TextRun,
- Tab,
- ExternalHyperlink,
- ImageRun,
- WidthType,
- TableRow,
- TableCell,
- MathRun
- } from 'docx'
- import { saveAs } from './utils'
- // 标题映射
- const titleLevelToHeadingLevel = {
- [TitleLevel.FIRST]: HeadingLevel.HEADING_1,
- [TitleLevel.SECOND]: HeadingLevel.HEADING_2,
- [TitleLevel.THIRD]: HeadingLevel.HEADING_3,
- [TitleLevel.FOURTH]: HeadingLevel.HEADING_4,
- [TitleLevel.FIFTH]: HeadingLevel.HEADING_5,
- [TitleLevel.SIXTH]: HeadingLevel.HEADING_6
- }
- function convertElementToParagraphChild(element) {
- if (element.type === ElementType.IMAGE) {
- return new ImageRun({
- data: element.value,
- transformation: {
- width: element.width||'',
- height: element.height||''
- }
- })
- }
- if (element.type === ElementType.HYPERLINK) {
- return new ExternalHyperlink({
- children: [
- new TextRun({
- text: element.valueList?.map(child => child.value).join(''),
- style: 'Hyperlink'
- })
- ],
- link: element.url||''
- })
- }
- if (element.type === ElementType.TAB) {
- return new TextRun({
- children: [new Tab()]
- })
- }
- if (element.type === ElementType.LATEX) {
- return new MathRun(element.value)
- }
- return new TextRun({
- font: element.font,
- text: element.value,
- bold: element.bold,
- size: `${(element.size || 16) / 0.75}pt`,
- color: Color(element.color).hex() || '#000000',
- italics: element.italic,
- strike: element.strikeout,
- highlight: element.highlight ? Color(element.highlight).hex() : undefined,
- superScript: element.type === ElementType.SUPERSCRIPT,
- subScript: element.type === ElementType.SUBSCRIPT,
- underline: element.underline ? {} : undefined
- })
- }
- function convertElementListToDocxChildren(
- elementList
- ) {
- const children = []
- let paragraphChild = []
- function appendParagraph() {
- if (paragraphChild.length) {
- children.push(
- new Paragraph({
- children: paragraphChild
- })
- )
- paragraphChild = []
- }
- }
- for (let e = 0; e < elementList.length; e++) {
- const element = elementList[e]
- if (element.type === ElementType.TITLE) {
- appendParagraph()
- children.push(
- new Paragraph({
- heading: titleLevelToHeadingLevel[element.level||''],
- children:
- element.valueList?.map(child =>
- convertElementToParagraphChild(child)
- ) || []
- })
- )
- } else if (element.type === ElementType.LIST) {
- appendParagraph()
- // 拆分列表
- const listChildren =
- element.valueList
- ?.map(item => item.value)
- .join('')
- .split('\n')
- .map(
- (text, index) =>
- new Paragraph({
- children: [
- new TextRun({
- text: `${
- !element.listStyle ||
- element.listStyle === ListStyle.DECIMAL
- ? `${index + 1}. `
- : `• `
- }${text}`
- })
- ]
- })
- ) || []
- children.push(...listChildren)
- } else if (element.type === ElementType.TABLE) {
- appendParagraph()
- const { trList } = element
- const tableRowList = []
- for (let r = 0; r < (trList||[]).length; r++) {
- const tdList = (trList||[])[r].tdList
- const tableCellList = []
- for (let c = 0; c < tdList.length; c++) {
- const td = tdList[c]
- tableCellList.push(
- new TableCell({
- columnSpan: td.colspan,
- rowSpan: td.rowspan,
- children: convertElementListToDocxChildren(td.value) || []
- })
- )
- }
- tableRowList.push(
- new TableRow({
- children: tableCellList
- })
- )
- }
- children.push(
- new Table({
- rows: tableRowList,
- width: {
- size: '100%',
- type: WidthType.PERCENTAGE
- }
- })
- )
- } else if (element.type === ElementType.DATE) {
- paragraphChild.push(
- ...(element.valueList?.map(child =>
- convertElementToParagraphChild(child)
- ) || [])
- )
- }
- else {
- if (/^\n/.test(element.value)) {
- appendParagraph()
- element.value = element.value.replace(/^\n/, '')
- }
- paragraphChild.push(convertElementToParagraphChild(element))
- }
- }
- appendParagraph()
- return children
- }
- export default function (command) {
- return function (options) {
- const { fileName } = options
- const {
- data: { header, main, footer }
- } = command.getValue()
- console.log(convertElementListToDocxChildren(main || []))
- const doc = new Document({
- sections: [
- {
- headers: {
- default: new Header({
- children: convertElementListToDocxChildren(header || [])
- })
- },
- footers: {
- default: new Footer({
- children: convertElementListToDocxChildren(footer || [])
- })
- },
- children: convertElementListToDocxChildren(main || [])
- }
- ]
- })
- console.log(doc)
- return
- Packer.toBlob(doc).then(blob => {
- saveAs(blob, `${fileName}.docx`)
- })
- }
- }
|