docx怎么转换成word文档(前端开发)
作者:麦兜 更新时间:2025-04-28 19:36:33 阅读 733
最近开发中遇到需要列表中的表格数据导出word,由于列表表格中的数据是动态表单拖拽产生的,格式就不太固定,想到的方案就是,固定个word模板,然后拿出表格的模板字段进行赋值导出,具体业务实现就不细说,下面说下导出实现。
需要的相关插件
docxtemplater
pizzip
file-saver
jszip-utils
jszip
docxtemplater-image-module-free
jszip: 是为了生成压缩包批量下载,不需要批量处理的可以不用安装
docxtemplater-image-module-free: 如果导出设计到图片的需要安装没有的也可以不用安装
安装
npm i docxtemplater pizzip jszip-utils file-saver jszip docxtemplater-image-module-free -S
处理逻辑
读取并获得模板文件的二进制内容 JSZipUtils.getBinaryContent('test.docx', (error, content) => {})
2.文件转zip 文件
const zip = new PizZip(content);
3.创建并加载docxtemplater实例对象
let doc = new docxtemplater().loadZip(zip).compile();
4.加载数据
5.模板定义
模板
测试数据
测试数据
效果展示
图片关键代码处理
批量下载处理
这个地方在打包完下载的时候加了个延迟处理,避免操作不完全
综合封装下
对上面的分散JS做下封装处理,新建exportWord.js
import docxtemplater from "docxtemplater"
import PizZip from "pizzip"
import { saveAs } from "file-saver"
import JSZipUtils from "jszip-utils"
import JSZip from 'jszip'
import ImageModule from "docxtemplater-image-module-free"
export const dataURLToBase64 = (url) => {
return new Promise((resolve, reject) => {
// 判断下传入的地址是不是已经是base64
const base64Regex = /^data:image\/(png|jpg|svg|svg\+xml);base64,/;
if (base64Regex.test(url)) {
return url;
}
const Img = new Image()
let dataURL = ''
Img.setAttribute('crossOrigin', 'Anonymous')
Img.src = url + '?v=' + Math.random()
Img.onload = function () {
// 要先确保图片完整获取到,这是个异步事件
const canvas = document.createElement('canvas') // 创建canvas元素
const width = Img.width // 确保canvas的尺寸和图片一样
const height = Img.height
canvas.width = width
canvas.height = height
canvas.getContext('2d').drawImage(Img, 0, 0, width, height) // 将图片绘制到canvas中
dataURL = canvas.toDataURL('image/jpeg') // 转换图片为dataURL
resolve(dataURL)
}
})
}
export const exportWord = ({ file = "input.docx", data, filename = "下载文档", fileType = "docx", folder = "下载文档" } = {}) => {
// 批量下载生成压缩包
const Zip = new JSZip()
if (Array.isArray(data)) {
data.map((item, index) => {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(file, (error, content) => {
// input.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
// 抛出异常
if (error) {
throw error
}
// 图片处理
let opts = {}
opts.centered = true; // 图片居中
opts.getImage = (tagValue, tagName) => {
return new Promise((resolve, reject) => {
JSZipUtils.getBinaryContent(tagValue, (error, content) => {
if (error) {
return reject(error);
}
return resolve(content);
});
});
}
opts.getSize = () => {
return [400, 200]
}
let imageModule = new ImageModule(opts);
// 创建一个JSZip实例,内容为模板的内容
const zip = new PizZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile();
let word = Zip.folder(folder)
doc.resolveData(item).then(() => {
doc.render();
const out = doc.getZip().generate({
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
});
word.file(`${item.filename ? item.filename : filename + index}.${fileType}`, out)
})
console.log(word, 'word')
})
})
setTimeout(() => {
Zip.generateAsync({ type: "blob" }) // zip下载
.then((content) => {
saveAs(content, `${folder}.zip`); // zip下载后的名字
});
}, 1000)
} else {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(file, (error, content) => {
// 抛出异常
if (error) {
throw error
}
// 图片处理
let opts = {}
opts.centered = true; // 图片居中,在word模板中定义方式为{%image}
opts.getImage = (tagValue, tagName) => {
return new Promise((resolve, reject) => {
JSZipUtils.getBinaryContent(tagValue, (error, content) => {
if (error) {
return reject(error);
}
return resolve(content);
});
});
}
opts.getSize = () => {
return [600, 300]
}
let imageModule = new ImageModule(opts);
const zip = new PizZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile();
// 如果包含异步数据,用resolveData,在回调之后再处理,如果都是同步数据,直接用setData就可以
doc.resolveData(data).then(() => {
try {
// 用模板变量的值替换所有模板变量
doc.render();
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
const out = doc.getZip().generate({
type: "blob",
mimeType:
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
// 将目标文件对象保存为目标类型的文件,并命名
saveAs(out, `${filename}.${fileType}`);
} catch (error) {
// 抛出异常
const e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
};
console.log(JSON.stringify({ error: e }));
throw error;
}
})
});
}
}
使用
导入上面定义的JS,使用exportWord方法
import {exportWord} from './exportWord'
const config = {
file: "test.docx",
filename:'下载文档',
fileType:'docx',
folder:'下载文档',
data: {}// 数据
}
exportWord(config)
参数说明:
开发的过程中也看到了别人写的,也借鉴参考学到了很多,这地方再进行整合下希望能帮助到也需要相似功能的你们。
声明:本文由"麦兜"发布,不代表"知识分享"立场,转载联系作者并注明出处:https://www.wuxiaoyun.com/life/170909.html