前端生成word文件的兩種方式總結
1、背景
在實際開發(fā)中,業(yè)務需要,需要把數(shù)據(jù)進行組合生成一個 word 文件
2、方式一:html-docx-js

注意,這個插件 最近的更新日期 八年之前了
2.1 具體代碼
核心邏輯
- 畫出 Word 文件內(nèi)容樣子
- 把 word文件內(nèi)容樣子的
DOM。傳入html-docx-js的asBlob方法 - 處理
blob格式的數(shù)據(jù),配合 a 標簽,直接在界面彈出文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>HTML to Word</title>
<script src="https://cdn.jsdelivr.net/npm/html-docx-js@0.3.1/dist/html-docx.min.js"></script>
<style>
.abc {
display: grid;
grid-template-columns: repeat(3, 1fr);
font-weight: bold;
}
.title {
font-weight: bold;
text-align: center;
vertical-align: middle;
}
.textCenter {
text-align: center;
}
tr,
td {
font-size: 12px;
}
* {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<div id="content">
<div style="font-size: 48px; font-weight: bold; text-align: center">質(zhì)量反饋單</div>
<div>反饋單單號: WLYD202412250049</div>
<table style="width: 100%;" border="1" cellspacing="0" cellpadding="0" class="textCenter">
<tr>
<td class="title">質(zhì)量問題主題</th>
<td colspan="3" class="textCenter">
你還是是大家看會玩空間的哈授課計劃的卡號夸獎哈首府卡迪夫好看就好的夸獎哈庫文件很大看見你是法務會計賀卡就是飯卡文化按時付款計劃啊空間未婚夫你還是是大家看玩空間的哈授課計劃的卡號夸獎哈首府卡迪夫好看就好的夸獎哈庫文件很大看見你是法務會計賀卡就是飯卡文化按時付款計劃啊空間未婚夫你還是是大家看會玩空間的哈授課計劃的卡號夸獎哈首府卡迪夫好看就好的夸獎哈庫文件很大看見你是法務會計賀卡就是飯卡文化按時付款計劃啊空間未婚夫
</td>
</tr>
<tr>
<td style="width: 15%;" class="title">反饋日期</td>
<td style="width: 35%;">2024-11-23</td>
<td style="width: 15%;" class="title">質(zhì)量問題等級</td>
<td style="width: 35%;">嚴重</td>
</tr>
<tr>
<td class="title">電站名稱</td>
<td>北京市超級充電站</td>
<td class="title">電站運營時間</td>
<td>2024-11-23</td>
</tr>
<tr>
<td class="title">項目類型</td>
<td>頭肩</td>
<td class="title">反饋公司</td>
<td>特來電新能源</td>
</tr>
<tr>
<td class="title">反饋人</td>
<td>呆呆狗</td>
<td class="title">反饋人電話</td>
<td>18856491536</td>
</tr>
<tr>
<td class="title">父級設備</td>
<td>箱變</td>
<td class="title">設備生產(chǎn)日期</td>
<td>2024-11-23</td>
</tr>
<tr>
<td class="title">子型號</td>
<td>子星號</td>
<td class="title">故障設備</td>
<td>故障設備</td>
</tr>
</table>
<!-- 現(xiàn)場問題描述 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="2" style="width: 15%;" class="title">現(xiàn)場問題描述</td>
<td style="width: 85%;height: 100px;vertical-align:top">edddd</td>
</tr>
<tr style="height: 40px;">
<td>填寫人: 呆呆狗</td>
</tr>
</table>
<!-- 糾正 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="7" style="width: 15%;text-align: center;" class="title">糾正</td>
<td colspan="2" style="width: 17%;text-align: center;" class="title">分類</td>
<td class="title" style="width: 10%;">數(shù)量</td>
<td class="title">措施</td>
<td class="title" style="width: 15%;">日期</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2">現(xiàn)場故障設備</td>
<td class="textCenter">12345.00</td>
<td>3</td>
<td class="textCenter">2024-01-01</td>
</tr>
<tr>
<td rowspan="3" style="text-align: center;">在庫</td>
<td style="text-align: center;">供應商在庫</td>
<td class="textCenter">3</td>
<td>4</td>
<td class="textCenter">2024-01-01</td>
</tr>
<tr>
<td style="text-align: center;">XXX在庫</td>
<td class="textCenter">3</td>
<td>4</td>
<td class="textCenter">2024-01-01</td>
</tr>
<tr>
<td style="text-align: center;">區(qū)域倉在庫</td>
<td class="textCenter">3</td>
<td>4</td>
<td class="textCenter">2024-01-01</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2">在市</td>
<td class="textCenter">2</td>
<td>3</td>
<td class="textCenter">2024-01-01</td>
</tr>
<tr>
<td style="text-align: center;" colspan="2">其他</td>
<td class="textCenter">2</td>
<td>3</td>
<td class="textCenter">2024-01-01</td>
</tr>
</table>
<!-- 具體原因分析 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="3" style="width: 15%;" class="title">原因分析</td>
<td style="width: 10%;" class="title">發(fā)生原因</td>
<td>2</td>
</tr>
<tr>
<td style="width: 10%;" class="title">流出原因</td>
<td>2</td>
</tr>
<tr>
<td style="width: 10%;" class="title">其他</td>
<td>2</td>
</tr>
</table>
<!-- 糾正措施 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="4" style="width: 15%;" class="title">糾正措施</td>
<td style="width: 10%;" class="title"></td>
<td class="title">措施</td>
<td style="width: 15%;" class="textCenter title">日期</td>
</tr>
<tr>
<td style="width: 10%;" class="title">發(fā)生</td>
<td>2</td>
<td style="width: 15%;" class="textCenter">2024-11-23</td>
</tr>
<tr>
<td style="width: 10%;" class="title">流出</td>
<td>2</td>
<td style="width: 15%;" class="textCenter">2024-11-23</td>
</tr>
<tr>
<td style="width: 10%;" class="title">舉一反三</td>
<td>2</td>
<td style="width: 15%;" class="textCenter">2024-11-23</td>
</tr>
</table>
<!-- 標準化 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="3" style="width: 15%;" class="title">標準化</td>
<td class="title">文件名稱</td>
<td style="width: 10%;" class="title">文件類型</td>
<td style="width: 15%;" class="title">日期</td>
</tr>
<tr>
<td>流出</td>
<td style="width: 10%;" class="textCenter">新增</td>
<td style="width: 15%;" class="textCenter">2024-11-23</td>
</tr>
<tr>
<td>舉一反三</td>
<td style="width: 10%;" class="textCenter">修改</td>
<td style="width: 15%;" class="textCenter">2024-11-23</td>
</tr>
</table>
<!-- 責任部門 和 責任部門領導審批 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td style="width: 15%;" class="title">責任部門</td>
<td class="textCenter">總裁辦</td>
<td style="width: 10%;" class="title">負責人</td>
<td style="width: 15%;" class="textCenter">呆呆狗</td>
<td style="width: 10%;" class="title">日期</td>
<td style="width: 15%;" class="textCenter">2024-01-01</td>
</tr>
<tr>
<td style="width: 15%;" class="title">責任部門領導審批</td>
<td colspan="3" class="textCenter">總裁辦</td>
<td style="width: 10%;" class="title">日期</td>
<td style="width: 15%;" class="textCenter">2024-01-01</td>
</tr>
</table>
<!-- 跟蹤驗證結果 -->
<table style="width: 100%;margin-top: -2px;" border="1" cellspacing="0" cellpadding="0">
<tr>
<td rowspan="3" style="width: 15%;" class="title">跟蹤驗證確認</td>
<td style="width: 85%;height: 100px;vertical-align:top">
缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結缺陷反酷點總結
</td>
</tr>
<tr style="height: 40px;">
<td>驗證結果: 關閉 無效</td>
</tr>
<tr style="height: 40px;">
<td>負責人: 呆呆狗 日期:2024-12-30 </td>
</tr>
<tr>
<td style="width: 15%;font-family: '宋體';font-size: 12pt;" class="title">備注</td>
<td style="font-family: '宋體';font-size: 12pt"></td>
</tr>
</table>
</div>
<button id="downloadButton">Download as Word</button>
<script>
document.getElementById("downloadButton").onclick = function () {
var content = document.getElementById("content").outerHTML;
var fullHtml = `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
* {
margin: 0;
padding: 0;
}
.title { font-weight: bold;text-align: center; vertical-align: middle;}
tr,
td {
font-size: 14px;
}
.textCenter {
text-align: center;
}
</style>
</head>
<body>
${content}
</body>
</html>
`;
var converted = htmlDocx.asBlob(fullHtml);
var link = document.createElement("a");
link.href = URL.createObjectURL(converted);
link.download = "document.docx";
link.click();
};
</script>
</body>
</html>
其實主要核心代碼就是下面這幾行
var converted = htmlDocx.asBlob(fullHtml);
var link = document.createElement("a");
link.href = URL.createObjectURL(converted);
link.download = "document.docx";
link.click();
用
html-docx-js的asBlob方法,傳入前端的DOM ,然后,用URL.createObjectURL創(chuàng)建一個blob 格式的鏈接,配合a標簽就可以了
2.2 前端生成word文件的樣式


2.3 總結
優(yōu)點
- 代碼簡單,上手速度快
- 不需要依賴于 后端,前端可以獨自處理
缺點
- 支持的 html、css 比較簡單,比如
flex、grid不支持 - 這個庫已經(jīng)很久不維護了
- 圖片需要轉成
base64才能放進去 - word的 行高、字體、字號 支持性較差
如果對于 word 文件的樣子要求不是很高,可以使用這個 方法,開發(fā)過程也相對比較簡單
3、方式二:pizzip + docxtemplater
3.1 具體代碼

核心思路
- 讀取預先設置好的 word 文件
- 解析word ,解析成二進制
- 創(chuàng)建docxtemplater實例
- 填充word 里面的數(shù)據(jù)
- 渲染word
- 獲取渲染后word的 blob 地址
- 下載 word
前提需要準備一個這樣的word 文件 ,下面的代碼是演示 插入 和 循環(huán) table,具體的文件在文章最頂部可以下載
這個word 里面的 語法可以參考這個鏈接 docxtemplater 語法演示
{Code} 在前端設置數(shù)據(jù)的時候,按照這個名字 和 要設置的值,組成 keyvalue 格式即可

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Docxtemplater Example</title>
<script src="https://cdn.jsdelivr.net/npm/pizzip@3.0.1/dist/pizzip.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/docxtemplater@3.29.0/build/docxtemplater.js"></script>
<script src="https://cdn.jsdelivr.net/npm/file-saver@2.0.5/dist/FileSaver.min.js"></script>
<script
src="https://unpkg.com/docxtemplater-image-module-free@3.0.0/dist/docxtemplater-image-module-free.js"></script>
</head>
<body>
<h1>Generate Word Document</h1>
<button id="generate">Download Word</button>
<script>
document.getElementById('generate').addEventListener('click', function () {
// 1、讀取word 文件
fetch('./template.docx')
.then(response => response.arrayBuffer())
.then(arrayBuffer => {
console.log('第一步', arrayBuffer);
// 2、解析word
const zip = new PizZip(arrayBuffer);
// 3、創(chuàng)建docxtemplater實例
const doc = new window.docxtemplater(zip, {
paragraphLoop: true,
linebreaks: true,
});
// 4、設置數(shù)據(jù)
doc.setData({
Code: "ZLFX202412280001",
name: "你好啊啊John Doe阿斯頓我是具體措施111你是你好啊啊John Doe阿斯頓我是具體措施111你是你好啊啊John Doe阿斯頓我是具體措施111你是你好啊啊John Doe阿斯頓我是具體措施111你是",
arr: [
{ name: "第一行", type: "新增", time: "2024-12-23" },
{ name: "第二行", type: "修改", time: "2024-12-23" },
{ name: "第三行", type: "新增", time: "2024-12-23" },
{ name: "第四行", type: "新增", time: "2024-12-23" },
{ name: "第五行", type: "新增", time: "2024-12-23" },
{ name: "第六行", type: "新增", time: "2024-12-23" },
{ name: "第七行", type: "刪除", time: "2099-12-23" },
],
});
try {
// 5、渲染word
doc.render();
} catch (error) {
console.error('Error rendering the document:', error);
return;
}
// 6、獲取渲染后的word
const output = doc.getZip().generate({ type: 'blob' });
// 7、下載word
saveAs(output, 'output.docx');
})
.catch(error => console.error('Error loading template:', error));
});
</script>
</body>
</html>
3.2 前端生成word文件的樣式
生成后的文件樣式如下。 圖片插入這個地方 官方說是可以,其他的文章也有實現(xiàn)的,但這個地方我沒實現(xiàn)。 據(jù)說是要用
docxtemplater-image-module這個庫

3.3 總結
優(yōu)點
- 樣式可控制
缺點
2. 需要預先設置 word 文件的樣式
4、參考鏈接
到此這篇關于前端生成word文件的兩種方式的文章就介紹到這了,更多相關前端生成word 文件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JS 清除字符串數(shù)組中,重復元素的實現(xiàn)方法
下面小編就為大家?guī)硪黄狫S 清除字符串數(shù)組中,重復元素的實現(xiàn)方法。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-05-05
BootStrap fileinput.js文件上傳組件實例代碼
這篇文章主要介紹了BootStrap fileinput.js文件上傳組件實例代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2017-02-02
從JQuery源碼分析JavaScript函數(shù)的apply方法與call方法
這篇文章主要介紹了從JQuery源碼分析JavaScript函數(shù)的apply方法與call方法,本文結合JQuery源碼和js高級程序設計再次探究apply方法與call方法,需要的朋友可以參考下2014-09-09
使用mixins實現(xiàn)elementUI表單全局驗證的解決方法
這篇文章主要介紹了使用mixins實現(xiàn)elementUI表單的全局驗證的解決方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2019-04-04
PNGHandler-借助JS讓PNG圖在IE下實現(xiàn)透明(包括背景圖)
PNGHandler-借助JS讓PNG圖在IE下實現(xiàn)透明(包括背景圖)...2007-08-08
javascript實現(xiàn)的元素拖動函數(shù)宿主為瀏覽器
這篇文章主要介紹了javascript實現(xiàn)的元素拖動,將相應的元素對象的引用傳到函數(shù)中2014-07-07

