DocTemplateTool

2023-11-07 21:01:18

你是否經常遇到這樣的場景:產品運營有著大量的報告需求,或者給客戶領導展現每週的運營報告?這些檔案類的任務可以交給運營同事,他們負責檔案排版和樣式,你作為開發人員你只需要提供資料來源,和一個對映表,告訴製作檔案的人哪些欄位可供使用。這樣一來分工明確,減少了很多不必要的溝通成本。

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);

它們將得到同樣的結果:

已知問題

作者資訊

作者:林小

郵箱:[email protected]

License

The MIT License (MIT)

專案地址

Github:DocTemplateTool