123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- // @ts-ignore
- import JSZipUtils from 'jszip-utils'
- import docxtemplater from 'docxtemplater'
- // @ts-ignore
- import { saveAs } from 'file-saver'
- import PizZip from 'pizzip'
- export const getBase64Sync = (imgUrl: string) => {
- return new Promise<string>(function (resolve, reject) {
- // 一定要设置为let,不然图片不显示
- let image = new Image()
- image.crossOrigin = 'anonymous'
- image.src = imgUrl
- image.onload = function () {
- let canvas = document.createElement('canvas')
- canvas.width = image.width
- canvas.height = image.height
- let context = canvas.getContext('2d')
- context?.drawImage(image, 0, 0, image.width, image.height)
- //图片后缀名
- let ext = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase()
- let quality = 0.8
- let dataurl = canvas.toDataURL('image/' + ext, quality)
- resolve(dataurl)
- }
- image.onerror = function (err) {
- reject(err)
- }
- })
- }
- export const base64DataURLToArrayBuffer = (dataURL: string) => {
- const base64Regex = /^data:image\/(png|jpg|jpeg|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 = Buffer.from(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
- }
- export const exportWordDocx = async (
- url: string,
- docxData: Record<string, any>,
- fileName: string
- ) => {
- const ImageModule = require('docxtemplater-image-module-free')
- JSZipUtils.getBinaryContent(url, async function (error: unknown, content: any) {
- if (error) {
- throw error
- }
- // 创建一个PizZip实例,内容为模板的内容
- let zip = new PizZip(content)
- // 创建并加载docxtemplater实例对象
- let doc = new docxtemplater().loadZip(zip)
- doc.attachModule(
- new ImageModule({
- getImage: (base64: string) => base64DataURLToArrayBuffer(base64),
- getSize: (buffer: string, base64: string, key: string) => {
- if (docxData.imagePages) {
- for (const row of docxData.imagePages) {
- for (const col of row) {
- for (const img of col) {
- if (img.img === base64) {
- return [img.width, img.height]
- }
- }
- }
- }
- }
- return [70, 70]
- }
- })
- )
- // 去除未定义值所显示的undefined
- doc.setOptions({
- nullGetter: function () {
- return ''
- }
- }) // 设置角度解析器Could not find a declaration file for module 'jszip-utils'.
- doc.setData({
- ...docxData
- })
- try {
- // 用模板变量的值替换所有模板变量
- doc.render()
- } catch (error: any) {
- let e = {
- message: error.message,
- name: error.name,
- stack: error.stack,
- properties: error.properties
- }
- console.log(JSON.stringify({ error: e }))
- throw error
- }
- // 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
- let out = doc.getZip().generate({
- type: 'blob',
- mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
- })
- // 将目标文件对象保存为目标类型的文件,并命名
- saveAs(out, fileName)
- })
- }
|