你是否經常遇到這樣的場景:產品運營有著大量的報告需求,或者給客戶領導展現每週的運營報告?這些文件類的任務可以交給運營同事,他們負責文件排版和樣式,你作為開發人員你只需要提供資料來源,和一個對映表,告訴製作文件的人哪些欄位可供使用。這樣一來分工明確,減少了很多不必要的溝通成本。
Document Template Tool
指定一個模板生成word或pdf檔案
執行單元測試以檢視示例!
功能 & 特點
- 基於佔位符的模板,可繼承原有樣式;
- 支援表格;
- 支援資料集合;
- 支援圖片;
- 提供Cli版本程式;
- 可擴充套件的介面封裝和元件。
快速開始
使用Cli
進入可執行檔案所在目錄,在命令提示符中執行DocTemplateTool.exe
引數列表:
引數 | 含義 | 用法 |
---|---|---|
-p | PatternFile | 指定一個Object檔案(Json), 作為資料來源件 |
-i | Input | 指定一個docx檔案作為模板 |
-o | Output | 指定一個路徑,作為匯出目標 |
-s | Source | 值為json |
-d | Destination | 值為word , pdf |
-w | WaitAtEnd | 指定時,程式執行完成後,將等待使用者輸入退出 |
-h | Help | 檢視幫助 |
示例
.\wtt.exe -p .\sample\data.json -i .\sample\template.docx -o .\output\test.docx -s json -d word
使用DocTemplateTool.Word類庫
在專案中引用DocTemplateTool.Word
dotnet add package DocTemplateTool.Word
由於Exporter返回的NPOI物件,你需要自行根據業務來處理結果,以及處理IO異常
byte[] docFileContent;
var docinfo = GetDocInfo(); // 準備資料
var result = Exporter.ExportDocxByObject("D:\\Template.docx", docinfo); //生成NPOI文件物件
//處理結果
using (var memoryStream = new MemoryStream())
{
result.Write(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
docFileContent = memoryStream.ToArray();
}
//寫入檔案或返回介面
File.WriteAllBytes("D:\\Result.docx", docFileContent);
佔位符
佔位符是指在模板中的一個標記,用於標記需要替換的文字或圖片,
文字佔位符的格式為:$欄位名稱[附加屬性]$
圖片佔位符的格式為:#欄位名稱[附加屬性]#
Exporter將掃描文件中所有佔位符,然後根據佔位符的名稱,從資料來源中獲取對應的文字值或圖片內容,替換到文件中。
文字
例如
姓名:$ClientName$
將被替換為
姓名:張三
圖片
確認大小
圖片佔位符支援附加屬性,用於指定圖片的寬度和高度,格式為:#欄位名稱[寬度,高度]#
#Graphic[431,266]#
將被替換為一個寬度為431,高度為266的圖片,單位為畫素。
若不指定寬度和高度,則使用預設圖片尺寸556*262。
在Word文件中,因為畫素大小是個相對值,頁面檢視100%時的大小為實際畫素尺寸,你可以使用截圖工具或標尺工具確認圖片的大小。
設定圖片
圖片源支援本地檔案和網路圖片以及Base64編碼的圖片。
從不同圖片來源生成文件的示例執行如下:
資料集合
由於NPOI限制,暫不支援表格的巢狀。
資料集合將以表格的形式呈現在文件中,因此你需要在模板中預留一個表格,Exporter將根據表中單元格的佔位符,填充表格各列的內容。
包含佔位符的行稱之為模板行。
定義
public class HealthReportDocInfo
{
...
public List<DetailList> BloodPressureList { get; set; }
}
public class DetailList
{
public string Name { get; set; }
public string Dept { get; set; }
public string Value { get; set; }
public string Result { get; set; }
}
配置模板表格:
預設以第二行作為模板行(通常第一行為表頭),你也可以根據實際情況跳過表頭,
例如在工資登記表示例中,表頭佔兩行的情況下,第三行為模板行,那麼你需要在配置中指定模板行的索引為2(索引從0開始)。
$Details[2]$
模板行的樣式將決定表格的樣式,因此你可以在模板行中設定表格的樣式,例如設定表格的字型,顏色,大小等。
示例執行如下圖:
其他示例
企業員工健康管理週報
心電圖報告
資料來源
資料來源支援從雜湊表(字典)或物件中獲取資料。
Exporter提供了ExportDocxByDictionary和ExportDocxByObject兩個方法,分別用於從雜湊表和物件中獲取資料。
從雜湊表中獲取資料:
var docinfo = new Dictionary<string, object>()
{
{"Dept", "XX科技股份有限公司" },
{"Date", DateTime.Now },
{"Number", "憑 - 202301111" },
{"Details", new List<Dictionary<string, object>>(){
new Dictionary<string, object>(){
{ "Type","銷售收款"},
{ "Name","應收款"},
{ "DeptorAmount",0},
{ "LenderAmount",50000}
},
new Dictionary<string, object>(){
{ "Type","銷售收款"},
{ "Name","預收款"},
{ "DeptorAmount",30000},
{ "LenderAmount",0}
},
new Dictionary<string, object>(){
{ "Type","銷售收款"},
{ "Name","現金"},
{ "DeptorAmount",20000},
{ "LenderAmount",0}
},
}},
{ "DeptorSum", 50000 },
{ "LenderSum", 50000 },
{ "ClientName", "XX科技股份有限公司" },
{ "Teller", "張三" },
{ "Maker", "李四" },
{ "Auditor", "王五" },
{ "Register", "趙六" },
};
var result = Word.Exporter.ExportDocxByDictionary(Path.Combine(templatePath_Doc, $"AccountingTemplate.docx"), docinfo, (s) => s);
從匿名物件中獲取資料:
var docinfo = new
{
Dept = "XX科技股份有限公司",
Date = DateTime.Now,
Number = "憑 - 202301111",
Details = new List<dynamic>() {
new
{
Type = "銷售收款",
Name = "應收款",
DeptorAmount = 0,
LenderAmount = 50000
},
new
{
Type = "銷售收款",
Name = "預收款",
DeptorAmount = 30000,
LenderAmount = 0
},
new
{
Type = "銷售收款",
Name = "現金",
DeptorAmount = 20000,
LenderAmount = 0
},
},
DeptorSum = 50000,
LenderSum = 50000,
ClientName = "XX科技股份有限公司",
Teller = "張三",
Maker = "李四",
Auditor = "王五",
Register = "趙六",
};
var result = Word.Exporter.ExportDocxByObject(Path.Combine(templatePath_Doc, $"AccountingTemplate.docx"), docinfo, (s) => s);
它們將得到同樣的結果:
已知問題
作者資訊
作者:林小
郵箱:jevonsflash@qq.com
License
The MIT License (MIT)