.NET 通過Word模板,使用AsposeWord進行數據動態導出Word

来源:https://www.cnblogs.com/lucasDC/archive/2023/03/25/17255910.html
-Advertisement-
Play Games

@ 先看一下導出的整體效果(如下圖),其中標註的區域都是通過後臺動態生成的: 一、先在Word中建立好表格模板 1.1、參數創建方法(Word和WPS) 1.1.1、Office中Word域的創建 1.1.1.1、選中指定的單元格 -> 點擊頭部工具欄中的”插入“ -> 選擇 ”文檔部件“ -> 選 ...


@

目錄

先看一下導出的整體效果(如下圖),其中標註的區域都是通過後臺動態生成的:

效果圖

一、先在Word中建立好表格模板

Word模板

1.1、參數創建方法(Word和WPS)

1.1.1、Office中Word域的創建

1.1.1.1、選中指定的單元格 -> 點擊頭部工具欄中的”插入“ -> 選擇 ”文檔部件“ -> 選擇 ”域“;

Office添加域

1.1.1.2、在左側的 “選擇域” 中找到 “Mergefield” -> 在功能變數名稱中填寫變數名(註:填寫的功能變數名稱需要和後臺中定義的欄位名數組中的欄位一樣,這樣才會填充對應的數據);

變數名

1.1.1.3、列表創建域

有列表區域的;需要進行迴圈插入。迴圈生成區域插入:輸入開始標識:TableStart:UserList,這裡的 UserList 要與 dt.TableName = "UserList"對應,這樣DataTable中的數據才會對應填充到表格中。
迴圈區域
再輸入其他DataTable中的欄位。
其他欄位列
最後記得同樣輸入一個結束標識:《《TableEnd:UserList》》《《最後的列名》》,把下方多餘的行刪除,在WORD模板生成時,會自動向下填充的。

自此,Word表格模板已創建完成!

1.1.2、Office中WPS域的創建

1.1.2.1、選中指定的單元格 -> 點擊頭部工具欄中的”插入“ -> 選擇 ”文檔部件“ -> 選擇 ”域“;

WPS域的創建

1.1.2.2、在左側的 “選擇域” 中找到 “郵件合併” -> 在域代碼填寫變數名:例如:(MERGEFIELD Textdwmc)(註:填寫的功能變數名稱需要和後臺中定義的欄位名數組中的欄位一樣,這樣才會填充對應的數據);

填充數據
自此,WPS中Word表格模板已創建完成!

二、添加相關的DLL文件

這裡的前提,你需要引用Aspose.Words.dll文件:using Aspose.Words;

2.1、添加相關的DLL文件

2.1.1、右鍵項目->管理NuGet程式包

管理NuGet程式包

2.1.2、在 管理NuGet程式包 中的瀏覽搜索:Aspose.Words(註:一定選擇21.8.0版本,這個版本能去水印,其餘高版本我暫沒試過( ̄▽ ̄)~*)點擊安裝即可!

安裝
自此,Aspose.Words就安裝成功!或者直接從網上下載指定的版本即可

三、編寫代碼(後臺.NET 代碼以VS 2019為例)

3.1、定義公共的欄位(註:定義的數組欄位要和Word模板中的功能變數名稱相同

/// <summary>
/// 公共欄位名字元串數組
/// </summary>
public static String[] fieldNames = new String[] { "Textdwmc", "Textdwdz", "Textfrdb", "Texthyxm", "Textmz", "Radioxb", "Textsfz", "Textdp", "Textlxdh", "Textwhcd", "Textgryx", "Texthyxz", "Textqyrs", "Textjxdz", "droprhxz", "Textrhsq", "Radiostate" };

/// <summary>
/// 文件名
/// </summary>
public static fileName="";

3.2、Word模板操作核心方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.IO;
//這裡的前提,你需要引用Aspose.Words.dll文件
using Aspose.Words;
using System.Data;

namespace AsposeWord//類名,可根據實際情況而定
{
    /// <summary>
    /// 通過WORD模板導出文檔
    /// </summary>
    public class WordModelEvent
    {
        /// <summary>
        /// 根據Word模板進行數據的導出Word操作
        /// </summary>
        /// <param name="modelDoc">模板路徑</param>
        /// <param name="exptDoc">導出文件名</param>
        /// <param name="fieldNames">欄位名字元串數組</param>
        /// <param name="fieldValues">欄位值數組</param>
        /// <param name="dt">需要迴圈的數據DataTable</param>
        /// <returns>返回的文檔路徑</returns>
        public static string ExpertWordToModel(string modelDoc, string exptDoc, String[] fieldNames, Object[] fieldValues, DataTable dt)
        {
            try
            {
                removeWatermark();//載入監聽,用於去除水印
                //string tempPath = HttpContext.Current.Server.MapPath("~/Demos/" + modelDoc + ".docx");//word模板路徑
                string tempPath = "../" + modelDoc + ".docx";
                //導出的WORD存放的位置
                const string saveFold = "../word/";
                //string outputPath = HttpContext.Current.Server.MapPath("~/" + saveFold);
                string outputPath = "" + saveFold;
                if (!Directory.Exists(outputPath))
                {
                    Directory.CreateDirectory(outputPath);
                }
                //生成的WORD文件名
                string fileName = exptDoc + "信息.docx";
                outputPath += fileName;
                //載入模板
                Document doc = new Document(tempPath);
                doc.MailMerge.Execute(fieldNames, fieldValues);
                //將我們獲得的DataTable類型的數據:EduDataTable放入doc方法中做處理
                if (dt.Rows.Count > 0 && dt!=null)
                {
                    doc.MailMerge.ExecuteWithRegions(dt);
                }
                //獲取下載地址
                String StrVisitURL = saveFold + fileName;
                //合併模版,相當於頁面的渲染
                doc.MailMerge.Execute(new[] { "PageCount" }, new object[] { doc.PageCount });
                //保存合併後的文檔
                doc.Save(outputPath);
                return StrVisitURL;
            }
            catch (Exception er)
            {
                return er.Message;
            }
        }

        /// <summary>
        /// 載入監聽,用於去除水印
        /// </summary>
        public static void removeWatermark()
        {
            new Aspose.Words.License().SetLicense(new MemoryStream(Convert.FromBase64String("PExpY2Vuc2U+CiAgPERhdGE+CiAgICA8TGljZW5zZWRUbz5TdXpob3UgQXVuYm94IFNvZnR3YXJlIENvLiwgTHRkLjwvTGljZW5zZWRUbz4KICAgIDxFbWFpbFRvPnNhbGVzQGF1bnRlYy5jb208L0VtYWlsVG8+CiAgICA8TGljZW5zZVR5cGU+RGV2ZWxvcGVyIE9FTTwvTGljZW5zZVR5cGU+CiAgICA8TGljZW5zZU5vdGU+TGltaXRlZCB0byAxIGRldmVsb3BlciwgdW5saW1pdGVkIHBoeXNpY2FsIGxvY2F0aW9uczwvTGljZW5zZU5vdGU+CiAgICA8T3JkZXJJRD4yMDA2MDIwMTI2MzM8L09yZGVySUQ+CiAgICA8VXNlcklEPjEzNDk3NjAwNjwvVXNlcklEPgogICAgPE9FTT5UaGlzIGlzIGEgcmVkaXN0cmlidXRhYmxlIGxpY2Vuc2U8L09FTT4KICAgIDxQcm9kdWN0cz4KICAgICAgPFByb2R1Y3Q+QXNwb3NlLlRvdGFsIGZvciAuTkVUPC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxFZGl0aW9uVHlwZT5FbnRlcnByaXNlPC9FZGl0aW9uVHlwZT4KICAgIDxTZXJpYWxOdW1iZXI+OTM2ZTVmZDEtODY2Mi00YWJmLTk1YmQtYzhkYzBmNTNhZmE2PC9TZXJpYWxOdW1iZXI+CiAgICA8U3Vic2NyaXB0aW9uRXhwaXJ5PjIwMjEwODI3PC9TdWJzY3JpcHRpb25FeHBpcnk+CiAgICA8TGljZW5zZVZlcnNpb24+My4wPC9MaWNlbnNlVmVyc2lvbj4KICAgIDxMaWNlbnNlSW5zdHJ1Y3Rpb25zPmh0dHBzOi8vcHVyY2hhc2UuYXNwb3NlLmNvbS9wb2xpY2llcy91c2UtbGljZW5zZTwvTGljZW5zZUluc3RydWN0aW9ucz4KICA8L0RhdGE+CiAgPFNpZ25hdHVyZT5wSkpjQndRdnYxV1NxZ1kyOHFJYUFKSysvTFFVWWRrQ2x5THE2RUNLU0xDQ3dMNkEwMkJFTnh5L3JzQ1V3UExXbjV2bTl0TDRQRXE1aFAzY2s0WnhEejFiK1JIWTBuQkh1SEhBY01TL1BSeEJES0NGbWg1QVFZRTlrT0FxSzM5NVBSWmJRSGowOUNGTElVUzBMdnRmVkp5cUhjblJvU3dPQnVqT1oyeDc4WFE9PC9TaWduYXR1cmU+CjwvTGljZW5zZT4=")));
        }
    }
}

3.3、通過Word模板生成新文件

/// <summary>
        /// 根據WORD模板基本信息
        /// </summary>
        /// <param name="id">需要迴圈的子數據的所屬上級ID</param>
        /// <returns>返回完成的文件下載路徑</returns>
        public static string GetWordEvent(string id)
        {
            try
            {
            //這裡是實例化Model,如果項目已有封裝的查詢資料庫信息的方法,直接使用參數“id”進行動態數據查詢即可
                memberUnit member = new memberUnit();
                member.id = "202204291157458529";
                member.Textdwmc = "長沙傑術有限公司";
                member.Textdwdz = "湖南省長";
                member.Textfrdb =null;
                member.Texthyxm = "gows";
                member.Textmz = "漢";
                member.Radioxb = "男";
                member.Textsfz = "4302685556951366";
                member.Textdp = "黨員";
                member.Textlxdh = "175125956569";
                member.Textwhcd = "高中";
                member.Textgryx = "[email protected]";
                member.Texthyxz = "wu";
                member.Textqyrs = "1444";
                member.Textjxdz = "湖南啊";
                member.droprhxz = "副會長";
                member.Textrhsq = "呃呃呃呃呃呃呃呃呃呃";
                member.Radiostate = "已處理";

                Object[] fieldValues = new object[fieldNames.Length];
                fieldValues[0] = member.Textdwmc;
                fieldValues[1] = member.Textdwdz;
                fieldValues[2] = member.Textfrdb;
                fieldValues[3] = member.Texthyxm;
                fieldValues[4] = member.Textmz;
                fieldValues[5] = member.Radioxb;
                fieldValues[6] = member.Textsfz;
                fieldValues[7] = member.Textdp;
                fieldValues[8] = member.Textlxdh;
                fieldValues[9] = member.Textwhcd;
                fieldValues[10] = member.Textgryx;
                fieldValues[11] = member.Texthyxz;
                fieldValues[12] = member.Textqyrs;
                fieldValues[13] = member.Textjxdz;
                fieldValues[14] = member.droprhxz;
                fieldValues[15] = member.Textrhsq;
                fieldValues[16] = member.Radiostate;
                DataTable dt = new DataTable();
                
            	#region /// 註意:如果在Word中沒有類似表格或者列表的數據,此處則不需要,刪除即可

                if (!string.IsNullOrEmpty(id))
                {
                    string sql = " SELECT * FROM TABLE WHERE id='' ORDER BY id DESC ";
                    dt = getDataTable(sql);
                    //這裡的UserList很關鍵,要與WORD模板的域設置對應,不是隨便寫的,後面還會用到
                    dt.TableName = "UserList";
                }

            	#endregion
            	
                string StrVisitURL = WordModelEvent.ExpertWordToModel("template", member.Textdwmc, fieldNames, fieldValues, dt);
                dt.Dispose();
                return StrVisitURL;
            }
            catch (Exception er)
            {
                return er.Message;
            }
        }

        /// <summary>
        /// 通過SQL獲得 DataTable
        /// </summary>
        /// <param name="sql">sql查詢語句</param>
        /// <param name="ConnectionString">你的數據鏈接字元串</param>
        /// <returns></returns>
        private static DataTable getDataTable(string sql, string ConnectionString = "")
        {
            SqlConnection cn = new SqlConnection(ConnectionString);
            SqlDataAdapter da = new SqlDataAdapter(sql, cn);
            DataTable ds = new DataTable();
            da.Fill(ds);
            cn.Dispose();
            return ds;
        }

3.4、調用方法

string url=  GetWordEvent("");

3.5、.NET 文件下載

3.5.1、ASP.NET 文件下載

/// <summary>
       ///字元流下載方法
       /// </summary>
       /// <param name="fileName">下載文件生成的名稱</param>
       /// <param name="fPath">下載文件路徑</param>
       /// <returns></returns>
        public void DownloadFile(string fileName, string fPath)
        {
            string filePath = Server.MapPath(fPath);//路徑
            //以字元流的形式下載文件
            FileStream fs = new FileStream(filePath, FileMode.Open);
            byte[] bytes = new byte[(int)fs.Length];
            fs.Read(bytes, 0, bytes.Length);
            fs.Close();
            Response.ContentType = "application/octet-stream";
            //通知瀏覽器下載文件而不是打開
            Response.AddHeader("Content-Disposition", "attachment;   filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
            Response.BinaryWrite(bytes);
            Response.Flush();
            if (!string.IsNullOrEmpty(filePath)&& filePath!=".")
            {
               System.IO.File.Delete(filePath+"/"+fileName);//在文件下載之後刪除其生成的文件
            }
            Response.End();
        }

3.5.2、ASP.NET MVC 的下載方法

/// <summary>
        /// 下載文件的方法
        /// </summary>
        /// <param name="path">文件絕對路徑</param>
        /// <param name="fileName">客戶端接收的文件名</param>
        /// <returns></returns>
        public static HttpResponseMessage Download(string path, string fileName)
        {
            var stream = File.OpenRead(path);
            HttpResponseMessage httpResponseMessage = new HttpResponseMessage(HttpStatusCode.OK);
            try
            {
                httpResponseMessage.Content = new StreamContent(stream);
                httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
                if (!string.IsNullOrEmpty(fileName))
                {
                    httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
                    {
                        FileName = HttpUtility.UrlEncode(fileName, Encoding.UTF8),
                    };
                }
                if (!string.IsNullOrEmpty(filePath)&& filePath!=".")
                {
                   System.IO.File.Delete(filePath+"/"+fileName);//在文件下載之後刪除其生成的文件
                }
                return httpResponseMessage;
            }
            catch
            {
                stream.Dispose();
                httpResponseMessage.Dispose();
                throw;
            }
        }

本文來自博客園,作者:TomLucas,轉載請註明原文鏈接:https://www.cnblogs.com/lucasDC/p/17255910.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前瞭解到通過UFUN函數UF_UGMGR_invoke_pdm_server可以調用Teamcenter ITK函數,從而可以獲取及編輯Teamcenter對象。UFUN中有樣例代碼,但是就是不知道怎麼使用,今天下午看了幫助文檔,想到需要把ITK的USER_invoke_pdm_server函數進 ...
  • 開發了一個Java庫的Google Bard API,可以自動化與AI對話了 Google Bard是Google提供的還在實驗階段的人工智慧對話服務。這明顯是對標ChatGPT來的,它可以提供更實時的答案,會基於Google強大的網頁數據。 為了更方便的使用並實現自動化,我寫了一個Java類庫,G ...
  • 信號槽連接 信號槽的連接,其實內部本質還是一個回調函數,主要是維護了信號發送Object的元對象里一個連接的列表。調用connect函數時,將槽的一系列信息,封裝成一個Connection,在發送信號時,通過這個列表,去回調槽函數。 1. 信號的連接 下麵列舉一種信號的連接方式,來大致講解一下信號的 ...
  • 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> OpenGL ES 特效 零基礎 OpenGL ES 學習路線推薦 : OpenGL ES 學習目錄 >> O ...
  • 原文地址: Java/Kotlin 使用Redis模擬發送郵件驗證碼 - Stars-One的雜貨小窩 Java中常用語連接Redis的庫有lettuce和jredis,一般是推薦lettuce,其具有非同步性,下麵兩種都簡單來使用如何實現功能 jredis 1.引入依賴 <dependency> < ...
  • 原文鏈接:https://www.zhoubotong.site/post/91.html 通常樹形菜單的實現基本就是遞歸調用,大部分場景畢竟這種數據不多,性能倒是並不突出, 下麵給個demo,有興趣的朋友可以看看: 新建一個city表: CREATE TABLE `city` ( `id` int ...
  • What is static and dynamic libraries 他們有什麼相同點嗎? 都是庫文件。對於調用庫文件的使用者來說,不管是靜態庫還是動態庫,調用的方式都是一樣的,沒什麼區別。 Differences between static and dynamic libraries 動態庫 ...
  • [NOIP2002 普及組] 選數 洛谷傳送門 點擊查看題目 題目描述 已知 n 個整數 x1,x2,.....,xn,以及 1 個整數 k(k<n)。從 n 個整數中任選 k 個整數相加,可分別得到一系列的和。例如當 n=4,k=3,4 個整數分別為 3,7,12,19 時,可得全部的組合與它們的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...