zhuliu 1 anno fa
parent
commit
26c8f5e023

File diff suppressed because it is too large
+ 1 - 0
src/assets/images/analysisTable.svg


+ 87 - 3
src/views/components/editor/editor.vue

@@ -213,6 +213,15 @@
           <div class="menu-item__analysis" @click="analysis">
             <i title="分析图"></i>
           </div>
+          <div class="menu-item__analysisTable" @click="showOption('menu-item__analysisTable')">
+            <i title="分析表"></i>
+            <div class="options">
+              <ul>
+                <li @click="insetTable(1)">表一</li>
+                <li @click="insetTable(2)">表二</li>
+              </ul>
+            </div>
+          </div>
           <!-- <div class="menu-item__hyperlink">
             <i title="超链接"></i>
           </div> -->
@@ -399,6 +408,7 @@
 import FileSaver from "file-saver";
 import htmlDocx from "html-docx-js/dist/html-docx";
 import Editor from '@hufe921/canvas-editor'
+
 import { Dialog } from './components/dialog/Dialog.js'
 import { Signature } from './components/signature/Signature.js'
 // import  {IEditorOption, ITableOption,IHeader, IFooter } from './options.js'
@@ -621,6 +631,8 @@ export default {
     export_WORD(){
         // var html = this.getHtml()
         const value = this.editorRef.command.getValue(this.options)
+        console.log(value)
+        // return
         var html = this.jsonToHtml(value.data.main)
         html = ` <!DOCTYPE html>
             <html lang="en">
@@ -628,7 +640,6 @@ export default {
             ${html}
             </body>
             </html>`
-            // console.log(html)
           var converted = htmlDocx.asBlob(html,{orientation:"landscape"})
           FileSaver.saveAs(converted,  new Date().toString() + ".docx");
     },
@@ -653,7 +664,79 @@ export default {
         };
       };
       proxyInputFile.click();
-    }
+    },
+    //显示插入分析图表的样式
+    showOption(str){
+      const rowMarginDom = document.querySelector(
+        '.'+str
+      )
+      const rowOptionDom = rowMarginDom.querySelector('.options')
+      rowOptionDom.classList.toggle('visible')
+    },
+    //插入表
+    insetTable(type){
+      var table ={
+              value: "",
+              type: "table",
+              trList: [
+                {
+                  height: 223.73809523809524,
+                  tdList: [
+                    {
+                      colspan: 1,
+                      rowspan: 1,
+                      value: [
+                        {
+                          value: "1",
+                          size: 16,
+                        },
+                      ],
+                    },
+                    {
+                      colspan: 1,
+                      rowspan: 1,
+                      value: [
+                        {
+                          value: "",
+                          type: "list",
+                          valueList: [
+                            {
+                              value: "\n你好\n世界",
+                            },
+                          ],
+                          listType: "ol",
+                          listStyle: "decimal",
+                        },
+                      ],
+                    },
+                    {
+                      colspan: 1,
+                      rowspan: 1,
+                      value: [
+                        
+                      ],
+                    },
+                  ],
+                  minHeight: 42,
+                },
+              ],
+              width: 554,
+              height: 223.73809523809524,
+              colgroup: [
+                {
+                  width: 184.66666666666666,
+                },
+                {
+                  width: 184.66666666666666,
+                },
+                {
+                  width: 184.66666666666666,
+                },
+              ],
+            }
+          
+            this.editorRef.command.executeInsertElementList([table])
+    },
   },
   async mounted () {
     const isApple = typeof navigator !== 'undefined' && /Mac OS X/.test(navigator.userAgent)
@@ -666,6 +749,7 @@ export default {
       },
       this.options
     )
+    // instance.use(docxPlugin)
       this.editorRef = instance;
       // cypress使用
       Reflect.set(window, 'editor', instance)
@@ -767,7 +851,7 @@ export default {
       saveDom.onclick = () => {
           const value = instance.command.getValue(this.options)
           const htmlVal = instance.command.getHTML()
-          // console.log(value,htmlVal,this.imageData)
+          // console.log(value,)
           this.$emit('save', value)// 保存数据传给父组件
       };
       // 快捷键保存

+ 5 - 2
src/views/components/editor/mixins/index.js

@@ -66,6 +66,9 @@ export default{
                             str = Number(str) * 100
                             str = str + '%'
                         }
+                        if(key == 'size' || key == 'width' || key == 'height'){
+                            str = (Number(str) || 16)
+                        }
                         styleContent = styleContent.replace('${'+ key +'}',str)
                     }
                     if(!style2[key]){
@@ -134,10 +137,10 @@ export default{
             var {style,style2} = this.getStyle(item)
             var str = value.value.replace(/\n/g,'<br>')
             var str1 = value.value.replace(/\n/g,'')
-            if(str1){
+            if(str1.trim()){
                 var index = value.value.indexOf('\n')
                 if(index == 0){
-                    str = value.value.replace(/\n/,'').replace(/\n/g,'<br>')
+                    str = value.value.replace(/\n/,'').replace(/\n/g,"<br>")
                 }
             }
             html += ` style='${style}'>${str}</span>`

+ 224 - 0
src/views/components/editor/plugin/exportdocx.js

@@ -0,0 +1,224 @@
+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`)
+    })
+  }
+}

+ 11 - 0
src/views/components/editor/plugin/index.js

@@ -0,0 +1,11 @@
+import Editor from '@hufe921/canvas-editor'
+import exportDocx from './exportdocx'
+// import importDocx from './importDocx'
+
+export default function docxPlugin(Editor) {
+  const command = Editor.command
+  // 导入文档
+//   command.executeImportDocx = importDocx(command)
+  // 导出文档
+  command.executeExportDocx = exportDocx(command)
+}

+ 7 - 0
src/views/components/editor/plugin/utils.js

@@ -0,0 +1,7 @@
+export function saveAs(blob, name) {
+  const a = document.createElement('a')
+  a.href = window.URL.createObjectURL(blob)
+  a.download = name
+  a.click()
+  window.URL.revokeObjectURL(a.href)
+}

+ 6 - 0
src/views/components/editor/style.css

@@ -332,6 +332,12 @@ ul {
 .menu-item__analysis i {
   background-image: url('~@/assets/images/analysis.svg');
 }
+.menu-item__analysisTable{
+  position: relative;
+}
+.menu-item__analysisTable i{
+  background-image: url('~@/assets/images/analysisTable.svg');
+}
 
 
 .menu-item__list .options {