前端实现下载word(多个word下载)-- docxtemplater

李和贵 2024-10-04 08:33:01 阅读 94

文章目录

🔎什么是docxtemplater?👻docxtemplater语法👻普通插值for循环选择图片(🌰代码)

👻实现下载👻安装依赖🌰完整代码关键逻辑解释

👻实现多文件下载👻🌰完整代码关键逻辑解释

👻推荐文章👻

🔎什么是docxtemplater?

docxtemplater 是一个邮件合并工具,以编程方式使用,处理条件、循环,并可扩展以插入图像、html或表格。

docxtemplater 使用 Javascript 对象(或 JSON)作为数据输入,因此也可以轻松地从其他语言中使用(请参阅docker 版本)。

它处理 docx 和 pptx 文件,并且通过附加模块,它可以处理 xlsx 模板

它的工作方式与模板引擎相同,您给它一个模板+一些数据,它就会输出一个生成的文档。

👻docxtemplater语法👻

普通插值

直接在word文档中使用<code>{}进行包裹字段即可,如图所示:

在这里插入图片描述

for循环

常用于列表中(此处只探讨简单的表格,复杂合并表格日后再做探讨)

参数对照

<code>{

...,

arr:[

{

name: "xxx",

gender: "xxx",

age: "xxx"

},

{

name: "xxx",

gender: "xxx",

age: "xxx"

},

{

name: "xxx",

gender: "xxx",

age: "xxx"

},

],

...

}

word中占位语法

在这里插入图片描述

选择

常用于勾选,和循环的语法一样

{#list}{/list} 循环、if判断

{#list}{/list}{^list}{/list} if else

图片(🌰代码)

docxtemplater-image-module-free // 导出图片的话需要这个插件

🌰官方代码

<code>JSZipUtils.getBinaryContent('examples/image-example.docx', function (error, content) { -- -->

if (error) {

console.error(error);

return;

}

var opts = { }

opts.centered = false;

opts.getImage = function (tagValue, tagName) {

return new Promise(function (resolve, reject) {

JSZipUtils.getBinaryContent(tagValue, function (error, content) {

if (error) {

return reject(error);

}

return resolve(content);

});

});

}

opts.getSize = function (img, tagValue, tagName) {

// FOR FIXED SIZE IMAGE :

return [150, 150];

// FOR IMAGE COMING FROM A URL (IF TAGVALUE IS AN ADRESS) :

// To use this feature, you have to be using docxtemplater async

// (if you are calling setData(), you are not using async).

return new Promise(function (resolve, reject) {

var image = new Image();

image.src = url;

image.onload = function () {

resolve([image.width, image.height]);

};

image.onerror = function (e) {

console.log('img, tagValue, tagName : ', img, tagValue, tagName);

alert("An error occured while loading " + tagValue);

reject(e);

}

});

}

var imageModule = new ImageModule(opts);

var zip = new JSZip(content);

var doc = new docxtemplater()

.loadZip(zip)

.attachModule(imageModule)

.compile();

doc.resolveData({

image: 'examples/image.png'

}).then(function () {

console.log('ready');

doc.render();

var out = doc.getZip().generate({

type: "blob",

mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",

});

saveAs(out, "generated.docx");

})

});

在这里就不做赘述,可以搜一下

👻实现下载👻

我们来实现一种最基础的下载,下载单个文件

安装依赖

npm install docxtemplater pizzip --save // 处理docx模板

npm install jszip-utils --save

npm install jszip --save

npm install file-saver --save // 处理输出文件

🌰完整代码

import Docxtemplater from "docxtemplater";

import PizZip from "pizzip";

import PizZipUtils from "pizzip/utils/index.js";

import { saveAs } from "file-saver";

function loadFile(url, callback) {

PizZipUtils.getBinaryContent(url, callback);

}

/**

* 渲染输出文件

* @param {*} fileUrl 文件所在地址

* @param {*} docxParamsArr doc文档参数数组

* @param {*} outDocName 输出文件名

*/

// eslint-disable-next-line no-unused-vars

export function renderDocs(fileUrl, docxParams, outDocName) {

loadFile(fileUrl, function (

error,

content

) {

if (error) {

throw error;

}

const zip = new PizZip(content);

const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });

doc.render(docxParams);

const out = doc.getZip().generate({

type: "blob",

mimeType:

"application/vnd.openxmlformats-officedocument.wordprocessingml.document"

});

saveAs(out, `${ outDocName}output.docx`);

});

}

关键逻辑解释

export function renderDocs(fileUrl, docxParams, outDocName) {...}:这行代码导出了renderDocs函数,这意味着它可以被其他模块导入和使用。函数有三个参数:fileUrl(文件的 URL)、docxParams(doc 文档的参数)和outDocName(输出文件名)。loadFile(fileUrl, function (error, content) {...}):在renderDocs函数内部,它调用了loadFile函数,传递了fileUrl和一个回调函数。loadFile函数可能是一个异步函数,用于从给定的 URL 加载文件内容。回调函数有两个参数:error(如果发生错误)和content(文件的内容)。if (error) {...}:在回调函数内部,检查是否发生错误。如果error存在,通过throw error;抛出错误,阻止函数继续执行。const zip = new PizZip(content);:如果成功加载文件内容,代码使用PizZip库创建一个新的PizZip对象。这个对象代表从 URL 下载的文件的 ZIP 归档,可以通过它来访问归档中的内容。const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });:创建一个Docxtemplater对象,将PizZip对象和一个配置对象传给它。配置对象设置了paragraphLooplinebreakstrue,这可能使得Docxtemplater在渲染过程中处理段落循环和行长换行。doc.render(docxParams);:用Docxtemplater对象的render方法来渲染docxParamsdocxParams可能是一个包含模板变量的对象,这些变量将被替换为模板中的相应占位符。const out = doc.getZip().generate({...});:渲染完成后,使用doc.getZip().generate({ type: "blob", mimeType: "..." })生成包含渲染后文档内容的BLOB。这个BLOB可以被保存为文件。saveAs(out, ${outDocName}output.docx);:最后,使用saveAs函数保存生成的文档。文件名由outDocNameoutput.docx组成,outDocName是函数参数,output.docx是固定的文件名后缀。

👻实现多文件下载👻

现实应用中难免会同时下载多个文件, 如果循环下载,浏览器会反复确认下载(如果浏览器开始下载提示的话),用户体验不是特别友好,操作也十分繁琐

我们可以把多个文件放入文件夹中,然后整成压缩包,进行下载

下面我们来实现一下(在上面的基础之上)

🌰完整代码

import Docxtemplater from "docxtemplater";

import PizZip from "pizzip";

import PizZipUtils from "pizzip/utils/index.js";

import { saveAs } from "file-saver";

function loadFile(url, callback) {

PizZipUtils.getBinaryContent(url, callback);

}

/**

* 渲染输出文件

* @param {*} fileUrl 文件所在地址

* @param {*} docxParamsArr doc文档参数数组

* @param {*} outDocName 输出文件名

*/

// eslint-disable-next-line no-unused-vars

export function renderDocs(fileUrl, docxParams, outDocName) {

loadFile(fileUrl, function (

error,

content

) {

if (error) {

throw error;

}

const zip = new PizZip(content);

const doc = new Docxtemplater(zip, { paragraphLoop: true, linebreaks: true });

doc.render(docxParams);

const out = doc.getZip().generate({

type: "blob",

mimeType:

"application/vnd.openxmlformats-officedocument.wordprocessingml.document"

});

saveAs(out, `${ outDocName}output.docx`);

});

}

关键逻辑解释

这段代码定义了一个名为renderDocs的函数,用于根据提供的文件URL、docx参数数组和输出文件名来渲染和生成文档文件。具体来说,renderDocs函数做了以下几件事:

检查docxParamsArr数组的长度:

如果数组长度为1,则创建一个Docxtemplater对象,将PizZip对象和一个配置对象传递给它。配置对象中设置了paragraphLooplinebreakstrue,然后使用该对象渲染docxParamsArr[0](数组中的第一个模板参数)。渲染完成后,它使用doc.getZip().generate({ type: "blob", mimeType: "... })生成一个包含渲染后文档内容的BLOB。最后,它使用saveAs(out, ${outDocName}output.docx);下载生成的文档,文件名根据提供的outDocName加上后缀output.docx

如果docxParamsArr数组的长度不为1,则创建一个JSZip对象用于生成一个多文档的ZIP文件:

对于docxParamsArr中的每个项,它创建一个Docxtemplater对象,将PizZip对象和一个配置对象传递给它。配置对象中设置了paragraphLooplinebreakstrue,然后使用该对象渲染相应的模板参数。对于每次渲染,它使用doc.getZip().generate({ type: "blob", mimeType: "... })生成一个BLOB,并将其作为文件添加到JSZip对象中,文件名根据索引值确定。渲染和添加所有文件后,它使用_zip.generateAsync({ type: "blob" })生成包含所有文件的ZIP BLOB。最后,它使用saveAs(content, ${outDocName}.zip);下载生成的ZIP文件,文件名根据提供的outDocName加上后缀.zip

注意

文件名字不要一样,要不然会直接替换,多个文件下载,文件名字要实现唯一性

👻推荐文章👻

docxtemplater官方文档

前端使用docxtemplater导出word文档最佳实践

docxtemplater-image-module-free



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。