欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Aspose Word 根据模板导出Word文档

程序员文章站 2022-03-27 08:29:04
...

网上有很多的关于WORD模板操作的文章,看了后,总是被其中一些关键点给打断了,在经过多次测试后,总算是成功生成了自己的WORD,今天详细分享下,希望能帮到需要的小白们。

首先来看下导出的效果

Aspose Word 根据模板导出Word文档

图片标注的区域,都是通过WORD模板生成的,特别是循环生成区域,估计都是大家想要的。下面就一步步来吧。

第一:引入Aspose.Words.dll ,网上都可以下载,这里不细说了。

第二: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;

///VanClean.Office 是我的命名空间,你可以自己调整
namespace VanClean.Office
{
    /// <summary>
    /// 通过WORD模板导出文档
    /// </summary>
    public class WordModelEvent
    {
        /// <summary>
        /// WORD模板操作
        /// </summary>
        /// <param name="modelDoc">模板路径</param>
        /// <param name="exptDoc">导出文件名</param>
        /// <param name="fieldNames"></param>
        /// <param name="fieldValues"></param>
        /// <param name="dt"></param>
        /// <returns></returns>
        public static string ExpertWordToModel(string modelDoc,string exptDoc, 
            String[] fieldNames, Object[] fieldValues,DataTable dt)
        {
            try
            {
                //WORD模板存放位置
                string tempPath = HttpContext.Current.Server.MapPath("~/templates/" + modelDoc + ".docx");
                //导出的WORD存放的位置
                const string saveFold = "uploads/word/";
                string outputPath = HttpContext.Current.Server.MapPath("~/" + saveFold);
                if (!Directory.Exists(outputPath))
                    Directory.CreateDirectory(outputPath); 
                //生成的WORD文件名
                string fileName = exptDoc + "[" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + "].docx";
                outputPath += fileName;
                //载入模板
                Document doc = new Document(tempPath); 
                doc.MailMerge.Execute(fieldNames, fieldValues);                
                //将我们获得的DataTable类型的数据:EduDataTable放入doc方法中做处理
                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;
            }
        }
    }
}

第三:通过WORD模板生成新文件

return PublicCode.RetTrueMsg(StrVisitURL);我返回的是JSON格式数据,你可直接返回 return StrVisitURL;即下载地址。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;

/// <summary>
        /// 根据WORD模板生成住户基础信息
        /// </summary>
        /// <param name="houseid"></param>
        /// <returns></returns>
        public static string GetWordEvent(string houseid)
        {
            try
            {
                String[] fieldNames = new String[]
                    {
                    "Fanghao",
                    "RegDate",
                    "UserName",
                    "Gender",
                    "Minzu",
                    "Zhengzhimm",
                    "IdCard",
                    "Qianchudi",
                    "Tel",
                    "Shuxing",
                    "BankZh",
                    "Gongyigang"
                    };
                PersonBase pb = SelectOne("", houseid);//通过houseid返回PersonBase对象,里面包括了fieldNames需要的字段信息,PersonBase自己定义下吧,SeleectOne()方法自己写一个。
                if(pb == null)
                {
                    return PublicCode.RetFalseMsg("没有查询到户主信息,请检查住户基础登记信息!");
                }

                Object[] fieldValues = new object[fieldNames.Length];                
                fieldValues[0] = FormatFanghao(pb.Fanghao);
                fieldValues[1] = DateTime.Now.ToString("yyyy年MM月dd日");
                fieldValues[2] = pb.Name;
                fieldValues[3] = pb.Xingbie;
                fieldValues[4] = pb.Minzu;
                fieldValues[5] = pb.Zhengzhimm;
                fieldValues[6] = pb.IdCard;
                fieldValues[7] = pb.qc_Xiangzhen + pb.qc_Xingzhengcun + pb.qc_Cunminxiaozu;
                fieldValues[8] = pb.Tel;
                fieldValues[9] = "";//属性
                fieldValues[10] = "";//银行账号
                fieldValues[11] = "";//公益岗

                
                string sql = "select Name,Huzhuguanxi,Xingbie,IdCard Card,'' Qita,'' UserGongyi";
                sql += " from TableName where HouseID='" + houseid + "' order by id asc";                
                DataTable dt = getDataTable(sql);
                //这里的UserList很关键,要与WORD模板的域设置对应,不是随便写的,后面还会用到
                dt.TableName = "UserList";
                //VanClean.Office这里命名空间注意修改
                string StrVisitURL = VanClean.Office.WordModelEvent.ExpertWordToModel("model", pb.Fanghao + pb.Name, fieldNames, fieldValues, dt);
                return PublicCode.RetTrueMsg(StrVisitURL);
            }
            catch(Exception er)
            {
                return er.Message;
            }
        }
        /// <summary>
        /// 格式化房号
        /// </summary>
        /// <param name="fanghao"></param>
        /// <returns></returns>
        private static string FormatFanghao(string fanghao)
        {
            try
            {
                string[] tmp = fanghao.Split('-');
                string str = Int32.Parse(tmp[0]).ToString() + "栋" + Int32.Parse(tmp[1]).ToString() + "单元" + Int32.Parse(tmp[2]).ToString() + "室";
                return str;
            }
            catch(Exception er)
            {
                return fanghao;
            }
        }

/// 通过SQL获得 DataTable
/// ConnectionString 你的数据链接字符串
private DataTable getDataTable(string sql)
        {
            SqlConnection cn = new SqlConnection(ConnectionString);
            SqlDataAdapter da = new SqlDataAdapter(sql, cn);
            DataTable ds = new DataTable();
            da.Fill(ds);
            return ds;
        }

第四:在运行前,你还需要建立WORD模板。

Aspose Word 根据模板导出Word文档

创建方法:

打开WORD-插入-文档部件-域

Aspose Word 根据模板导出Word文档

如图输入域名,记得与 fieldNames 中字字段对应。

String[] fieldNames = new String[]
                    {
                    "Fanghao",
                    "RegDate",
                    "UserName",
                    "Gender",
                    "Minzu",
                    "Zhengzhimm",
                    "IdCard",
                    "Qianchudi",
                    "Tel",
                    "Shuxing",
                    "BankZh",
                    "Gongyigang"
                    };

Aspose Word 根据模板导出Word文档

循环生成区域插入:输入开始标识:TableStart:UserList,这里的 UserList 要与 dt.TableName = "UserList"对应,这样DataTable中的数据才会对应填充到表格中。

Aspose Word 根据模板导出Word文档

再输入其他字段

Aspose Word 根据模板导出Word文档

最后记得同样输入一个结束标识:TableEnd:UserList,把下方多余的行删除,在WORD模板生成时,会自动向下填充的。

第五:完成以上工作,就可以调用了,调用就很简单了。

我使用的WEB服务,然后使用AJAX调用,你也可以直接使用方法就可以调用了。

HTML代码
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="test.aspx.cs" Inherits="comm_test" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
        </div>
    </form>
</body>
</html>

调用代码
protected void Button1_Click(object sender, EventArgs e)
    {
        string houseid = "testid";
        GetWordEvent(houseid);
    }