[C#]TemplateEngine.Docx Word產出好工具

TemplateEngine.Docx Word產出好工具

前言

最近工作上面遇到一個需求,需要根據DB資料去產製一份審核書,

需要處理的部分是使用者個人資訊部分(姓名、電話、地址),

和一些相關表格(Table)資訊。

來源

這個套件主要是由 DocX library 衍生出來,透過維護Word Template在根據設定好的控制項去填寫內容,

所以整個過程會分為兩個部分。

  1. 建立一個 Word Template 檔案
  2. 程式填寫此檔案內容

安裝

我們可以透過 Nuget 來安裝此套件,

Steps 1

建立一個簡單的word Template 供後續程式操作,這邊要特別注意的是 Word 本身是沒有開啟開發者模式的,需要去左上方檔案頁籤

看到開發者頁籤出現就代表第一步驟已經完成囉~

內容控制項設定

  1. 開啟設計模式
  2. 新增內容控制項
  3. 輸入控制項文字
  4. 設定邊標題與標籤

重複控制項

  1. 開啟設計模式
  2. 新增重複控制項
  3. 設定邊標題與標籤
  4. 欄位放置文字控制項

根據上方兩項設定我們就可以透過程式來操作填寫我們的Word Template,

透過置換我們預留的控制項,達成資料填寫的目的。

Steps 2

透過程式填寫檔案內容,範例由一個基本的webform 專案示範,

畫面上僅有一個簡單的 button 來產出word文件。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.UI;
using TemplateEngine.Docx;

namespace DocXTemplateEngineDemo
{
    public partial class index : Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void downloadFile_btn_OnClick(object sender, EventArgs e)
        {
            //1.複製至目標路徑
            var targetPath = "D:/demo/";
            string fileName = $"{DateTime.Now:yyyyMMddHHmmss}.docx";
            File.Copy(Server.MapPath("~/Template/template.docx"), targetPath + fileName);

            //2.設定檔案內容

            //FieldContent部分
            var valuesToFill = new Content();
            valuesToFill.Fields.Add(new FieldContent("name", "王小明"));
            valuesToFill.Fields.Add(new FieldContent("special_1", "■"));
            valuesToFill.Fields.Add(new FieldContent("special_2", "□"));

            var tableContent = new TableContent("row");
            foreach (var f in FakeData())
                tableContent.AddRow(
                    new FieldContent("r_name", f.Name),
                    new FieldContent("r_chinese", f.Chinese),
                    new FieldContent("r_english", f.English),
                    new FieldContent("r_math", f.Math)
                );

            //TableContent部分
            valuesToFill.Tables.Add(tableContent);
            var avg_chinese = FakeData().Average(x => Convert.ToDecimal(x.Chinese));
            var avg_english = FakeData().Average(x => Convert.ToDecimal(x.English));
            var avg_math = FakeData().Average(x => Convert.ToDecimal(x.Math));
            valuesToFill.Fields.Add(new FieldContent("avg_chinese", avg_chinese.ToString("0.0")));
            valuesToFill.Fields.Add(new FieldContent("avg_english", avg_english.ToString("0.0")));
            valuesToFill.Fields.Add(new FieldContent("avg_math", avg_math.ToString("0.0")));

            //3.儲存變更
            using (var outputDocument = new TemplateProcessor(targetPath + fileName).SetRemoveContentControls(true))
            {
                outputDocument.FillContent(valuesToFill);
                outputDocument.SaveChanges();
            }
        }

        //假資料
        public List<ScoreSheet> FakeData()
        {
            return new List<ScoreSheet>
            {
                new ScoreSheet
                {
                    Name = "王XX",
                    Chinese = "100",
                    English = "70",
                    Math = "90"
                },
                new ScoreSheet
                {
                    Name = "鄭XX",
                    Chinese = "90",
                    English = "60",
                    Math = "80"
                },
                new ScoreSheet
                {
                    Name = "陳XX",
                    Chinese = "80",
                    English = "50",
                    Math = "60"
                },
                new ScoreSheet
                {
                    Name = "張XX",
                    Chinese = "70",
                    English = "80",
                    Math = "70"
                }
            };
        }

        public class ScoreSheet
        {
            public string Name { get; set; }
            public string Chinese { get; set; }
            public string English { get; set; }
            public string Math { get; set; }
        }
    }
}

 

產出結果

結論

此專案範本 Gitbub 範例

目前專案僅使用到兩種就解決了問題,所以只有介紹上面兩種FiledContent、TableContent,

下方是原專案提供所有的Content,若有需要可以自行實作。

原本專案 Github : https://github.com/UNIT6-open/TemplateEngine.Docx