zhouwx
2025-11-06 9c2d854d62aa70e4753f43fbede7960381b9804b
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
105
106
107
108
109
110
111
112
//引入工具
import PizZip from 'pizzip';
import Docxtemplater from 'docxtemplater';
import JSZipUtils from 'jszip-utils';
import { saveAs } from 'file-saver';
import ImageModule from 'docxtemplater-image-module-free'; // 新增:图片处理模
 
// 加载 .docx 模板文件
function loadFile(url, callback) {
    JSZipUtils.getBinaryContent(url, callback);
}
 
// 下载生成的文档
export function download(file, name) {
 
}
// 辅助函数:将 base64 图片转为 Uint8Array(图片模块需要此格式)
function base64ToUint8Array(base64) {
    // 去掉 base64 前缀(如 "data:image/png;base64,")
    const base64WithoutPrefix = base64.replace(/^data:image\/\w+;base64,/, '');
    const binaryString = atob(base64WithoutPrefix);
    const length = binaryString.length;
    const uint8Array = new Uint8Array(length);
    for (let i = 0; i < length; i++) {
        uint8Array[i] = binaryString.charCodeAt(i);
    }
    return uint8Array;
}
 
 
// 生成并下载 Word 文档(templatePath是word文档模版地址,data是对应的数据)
export function generateWordDocument(templatePath, data, name) {
        loadFile(templatePath, function (error, content) {
            if (error) {
                throw error
                return;
            }
 
            try {
                // 新版创建解析器的正确方式(无需 import AngularParser)
                const parser = (tag, _variable) => {
                    return {
                        get(scope) {
                            if (scope[tag] !== undefined) {
                                return scope[tag] || '';
                            }
                            // 处理特殊变量(如 $first)
                            if (tag.startsWith('$')) {
                                const varName = tag.slice(1);
                                return scope[varName] || '';
                            }
                            return '';
                        }
                    };
                };
                // 1. 配置图片处理规则(核心)
                const imageModule = new ImageModule({
                    // 获取图片:根据传入的图片数据(base64)转为模块需要的格式
                    getImage: function (tagValue, tagName) {
                        // tagValue:data 中对应图片键的值(必须是 base64 字符串)
                        // tagName:图片占位符的键名(如 "avatar")
                        return base64ToUint8Array(tagValue);
                    },
                    // 设置图片尺寸:返回 [宽度, 高度](单位:px),可动态调整
                    getSize: function (tagValue, tagName) {
 
                        // 示例:根据不同的图片键,返回不同尺寸
                        switch (tagName) {
                            case 'avatar': // 头像:200x200
                                return [200, 200];
                            case 'coverImg': // 封面图:600x300
                                return [600, 300];
                            default: // 默认尺寸:400x300
                                return [80, 100];
                        }
                    }
                });
                // 加载模板文件内容到 PizZip
                const zip = new PizZip(content);
                const doc = new Docxtemplater(zip, {
                    paragraphLoop: true,
                    linebreaks: true,
                    modules: [imageModule] // 关键:注入图片模块
                });
 
                // const parser = new AngularParser();
                // doc.setOptions({ parser });
 
 
                // 设置模板中的占位符数据
                doc.setData(data);
 
                // 渲染文档
                doc.render();
 
                // 生成最终的文档 Blob
                const fileWord = doc.getZip().generate({
                    type: 'blob',
                    mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
                });
 
                saveAs(fileWord, name);
 
                // // 返回生成的文档 Blob
                // resolve(fileWord);
            } catch (error) {
                console.error('Error rendering document:', error);
                throw error
            }
        });
 
}