|
@@ -2,6 +2,8 @@ import Docxtemplater from 'docxtemplater'
|
|
import PizZip from 'pizzip'
|
|
import PizZip from 'pizzip'
|
|
import JSZipUtils from 'jszip-utils'
|
|
import JSZipUtils from 'jszip-utils'
|
|
import { saveAs } from 'file-saver'
|
|
import { saveAs } from 'file-saver'
|
|
|
|
+import ImageModule from 'docxtemplater-image-module-free'
|
|
|
|
+import expressions from 'angular-expressions'
|
|
|
|
|
|
/**
|
|
/**
|
|
4. 导出docx
|
|
4. 导出docx
|
|
@@ -9,6 +11,7 @@ import { saveAs } from 'file-saver'
|
|
6. @param { Object } data 文件中传入的数据
|
|
6. @param { Object } data 文件中传入的数据
|
|
7. @param { String } fileName 导出文件名称
|
|
7. @param { String } fileName 导出文件名称
|
|
*/
|
|
*/
|
|
|
|
+
|
|
export const exportDocx = (tempDocxPath, data, fileName) => {
|
|
export const exportDocx = (tempDocxPath, data, fileName) => {
|
|
// 读取并获得模板文件的二进制内容
|
|
// 读取并获得模板文件的二进制内容
|
|
JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
|
|
JSZipUtils.getBinaryContent(tempDocxPath, (error, content) => {
|
|
@@ -22,6 +25,25 @@ export const exportDocx = (tempDocxPath, data, fileName) => {
|
|
const uint8Array = new Uint8Array(content);
|
|
const uint8Array = new Uint8Array(content);
|
|
console.log("文件内容字节:", uint8Array);
|
|
console.log("文件内容字节:", uint8Array);
|
|
const zip = new PizZip(content)
|
|
const zip = new PizZip(content)
|
|
|
|
+ // 处理图片
|
|
|
|
+ const imageModule = new ImageModule({
|
|
|
|
+ getImage: async (tagValue) => {
|
|
|
|
+ if (tagValue.startsWith('studentSignature')) {
|
|
|
|
+ const imagePath = data.images[tagValue]; // 获取学生签名路径
|
|
|
|
+ console.log(`学生签名路径: ${imagePath}`);
|
|
|
|
+ return await loadImage(imagePath);
|
|
|
|
+ } else if (tagValue.startsWith('supervisorSignature')) {
|
|
|
|
+ const imagePath = data.images[tagValue]; // 获取导师签名路径
|
|
|
|
+ console.log(`导师签名路径: ${imagePath}`);
|
|
|
|
+ return await loadImage(imagePath);
|
|
|
|
+ }
|
|
|
|
+ console.error(`未找到图片路径: ${tagValue}`);
|
|
|
|
+ return null;
|
|
|
|
+ },
|
|
|
|
+ getSize: (img, tagValue) => {
|
|
|
|
+ return [100, 100]; // 宽高调整
|
|
|
|
+ }
|
|
|
|
+ });
|
|
const doc = new Docxtemplater().loadZip(zip)
|
|
const doc = new Docxtemplater().loadZip(zip)
|
|
console.log(doc)
|
|
console.log(doc)
|
|
doc.setData(data)
|
|
doc.setData(data)
|
|
@@ -47,4 +69,28 @@ export const exportDocx = (tempDocxPath, data, fileName) => {
|
|
}) // Output the document using Data-URI
|
|
}) // Output the document using Data-URI
|
|
saveAs(out, fileName)
|
|
saveAs(out, fileName)
|
|
})
|
|
})
|
|
|
|
+}
|
|
|
|
+/**
|
|
|
|
+ * 加载图片
|
|
|
|
+ * @param { String } url 图片的 URL 或 Base64 编码
|
|
|
|
+ * @returns { Promise<Uint8Array> } 图片的 Uint8Array 数据
|
|
|
|
+ */
|
|
|
|
+const loadImage = async (url) => {
|
|
|
|
+ if (url.startsWith('data:image')) {
|
|
|
|
+ // 处理 Base64 编码
|
|
|
|
+ const base64Data = url.split(',')[1];
|
|
|
|
+ const byteCharacters = atob(base64Data);
|
|
|
|
+ const byteNumbers = new Array(byteCharacters.length);
|
|
|
|
+ for (let i = 0; i < byteCharacters.length; i++) {
|
|
|
|
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
|
|
+ }
|
|
|
|
+ return new Uint8Array(byteNumbers);
|
|
|
|
+ } else {
|
|
|
|
+ // 处理 URL
|
|
|
|
+ const response = await fetch(url);
|
|
|
|
+ if (!response.ok) {
|
|
|
|
+ throw new Error(`加载图片时出现错误: ${response.statusText}`);
|
|
|
|
+ }
|
|
|
|
+ return new Uint8Array(await response.arrayBuffer());
|
|
|
|
+ }
|
|
}
|
|
}
|