在工做中遇到一個需求,須要用戶本身建立一個word模板,而後上傳到網頁端再把咱們的數據渲染word對應的地方並導出。html
翻了半天github決定用如下技術實現:git
Docxtemplater能夠獲取到導入的word數據中用特殊符號(例如‘{}’)包裹的變量,並給其賦值,從而實現對模板的賦值。github
如下是用angular的一個簡單實現:bash
import { Component } from '@angular/core';
import * as docxtemplater from 'docxtemplater';
import * as inspect from 'docxtemplater/js/inspect-module';
import * as PizZip from 'pizzip';
import * as pizzipUtils from 'pizzip/utils';
import * as FileSaver from 'file-saver';
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
export class AppComponent {
// 加載文件
loadFile(url, callback) {
pizzipUtils.getBinaryContent(url, callback); // 將文件加載成二進制文件
}
generate() {
this.loadFile('../assets/test.docx', function(error, content) {
if (error) { throw error; }
const zip = PizZip(content); // 將內容轉化PizZip對象
const doc = new docxtemplater().loadZip(zip); // 得到templater對象
// 對word中的變量進行賦值
doc.setData({
title: '模板測試',
anthor: 'elc',
time: '2019-10-2',
content: `docxtemplater is a mail merging tool that is used programmatically and handles conditions,
loops, and can be extended to insert anything (tables, html, images).`
});
try {
doc.render(); // 將賦值渲染到word數據中
} catch (error) {
const e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties,
};
console.log(JSON.stringify({error: e}));
throw error;
}
// 生成輸出數據,數據類型爲FileSaver插件能夠識別的blob類型,還能夠生成string, base64, uint8array, arraybuffer類型
console.log(doc.getZip().generate)
const out = doc.getZip().generate({
type: 'blob'
});
FileSaver.saveAs(out, 'output.docx'); // 保存,並輸出
});
}
}
複製代碼
這是傳入的文件模板:app
這是導出文件的結果:oop
導入循環數據的模板用‘{#}’ 和‘{/}’包裹。 例如: 測試
doc.setData({
heros: [
{
heroName: 'Lina',
heroCamp: 'radiant',
heroEquipment: 'drogon'
},
{
heroName: 'Earth Shocker',
heroCamp: 'radiant',
heroEquipment: 'blink dragger'
},
{
heroName: 'Lion',
heroCamp: 'Dire',
heroEquipment: 'drogon'
}
]
});
複製代碼
這樣的循環能夠用在表格中ui
doc.setData({
heroTable: [
{
hero_name: 'Lina',
hero_camp: 'radiant',
hero_equipment: 'drogon'
},
{
hero_name: 'Earth Shocker',
hero_camp: 'radiant',
hero_equipment: 'blink dragger'
},
{
hero_name: 'Lion',
hero_camp: 'Dire',
hero_equipment: 'drogon'
},
]
});
複製代碼
#開頭的變量能夠添加條件來控制導入, {/}能夠表示或,來進行多種條件的控制。不過這種方法須要導入angular parse插件並設置模板才能使用。 以下例:this
doc.setData({
users: [
{
name: 'John'
},
{
name: 'Mary'
},
{
name: 'Jane'
},
{
name: 'Sean'
}
]
});
複製代碼
只要使用基本用法和循環數據,起始就能夠完成幾乎全部的模板製做。官方另外提供了一些table,html,grid等更加便捷的插件,不過要收費。。。url
一個容易踩的坑,在word的模板中不容許任何空格{title}和{ title }是兩個變量。
要動態獲取模板變量的話,須要導入inspect module來解析數據:
import * as inspect from 'docxtemplater/js/inspect-module';
getTages(doc: docxtemplater) {
const iModule = inspect();
doc.attachModule(iModule);
doc.render();
const tags = iModule.getAllTags();
console.log(tags);
return tags;
}
複製代碼
其餘更詳細的東西請參閱文檔 docxtemplater.readthedocs.io/en/latest/i…