guoshipeng
2023-08-18 f4dec5e5b3a400a6c0fe8cc7fade6b6a01621bfa
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import Docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import { imageToBase64 } from '@/utils/imageExchange'
 
let base64Img = ''
export const exportDocx = (tempDocxPath, data, fileName) => {
  const ImageModule = require('docxtemplater-image-module-free')
  // 读取并获得模板文件的二进制内容
  JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
    if (error) {
      throw error
    }
    // 图片处理
    const opts = {}
    opts.centered = true // 图片居中,在word模板中定义方式为{%%image}
    opts.fileType = 'docx'
 
    const p = new Promise(resolve => {
      const images1 = []
      if (data.fileList.length > 0) {
        data.fileList.forEach(image => {
          main(image.url, (base64) => {
            images1.push({ src: base64 })
            if (images1.length === data.fileList.length) {
              resolve(images1)
            }
          })
        })
      } else {
        resolve(images1)
      }
    })
    p.then(res => {
      opts.getImage = function(image) {
        return base64DataURLToArrayBuffer(image)
      }
      opts.getSize = function() {
        return [180, 120]
      }
 
      const imageModule = new ImageModule(opts)
 
      const zip = new PizZip(content)
      const doc = new Docxtemplater().loadZip(zip)
      doc.attachModule(imageModule)
      const obj = { ...data, images: res }
      doc.setData({ ...obj })
      try {
        // render the document (replace all occurences of {first_name} by John, {last_name} by Doe, ...)
        doc.render()
      } catch (error) {
        const e = {
          message: error.message,
          name: error.name,
          stack: error.stack,
          properties: error.properties
        }
        console.log({
          error: e
        })
        // The error thrown here contains additional information when logged with JSON.stringify (it contains a property object).
        throw error
      }
      const out = doc.getZip().generate({
        type: 'blob',
        mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
      }) // Output the document using Data-URI
      saveAs(out, fileName)
    })
  })
}
 
function base64DataURLToArrayBuffer(dataURL) {
  const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/
  if (!base64Regex.test(dataURL)) {
    return false
  }
  const stringBase64 = dataURL.replace(base64Regex, '')
  let binaryString
  if (typeof window !== 'undefined') {
    binaryString = window.atob(stringBase64)
  } else {
    binaryString = new Buffer(stringBase64, 'base64').toString('binary')
  }
  const len = binaryString.length
  const bytes = new Uint8Array(len)
  for (let i = 0; i < len; i++) {
    const ascii = binaryString.charCodeAt(i)
    bytes[i] = ascii
  }
  return bytes.buffer
}
 
function main(url, cb) {
  var image = new Image()
  image.crossOrigin = ''
  image.src = url
  image.onload = function() {
    base64Img = imageToBase64(image)
    cb && cb(base64Img)
  }
}