ASP.Net利用DocX-Xceed工具读取word模板添加内容导出浏览器下载

一、工具简介

(1)、DocX是一个对word进行操作的开源轻量级.net工具,可创建自定义文档和加载模板文档按照规则添加内容,然后保存或导出。本例是通过加载一个已设计好的模板,页面发起导出某某单内容,将单数据传到后台,后台按照模板填充内容,并将文档导出浏览器下载。

(2)、下载地址:https://github.com/xceedsoftware/docx

(3)、工具项目运行环境:.NET framework4.0和VS2010或更高版本

(4)、工具使用:将下载的工具项目用VS工具打开运行Xceed.Words.NET.sln,项目自带很多操作的例子,这里不做过多说明,自行研究。运行后会在Xceed.Words.NET.Examples项目bin\Debug目录下产生编译文件Xceed.Document.NET.dll和Xceed.Words.NET.dll,将这两个文件复制到某个目录,然后在自己开发的项目下引用这两个文件就可以在项目中使用了。

本例模板格式

 

 

二、后台代码

public class WordHelper
{
  private static WordTemplateModel temp = new WordTemplateModel();//数据模型
  /// <summary>
  /// Load a document and replace texts following a replace pattern.
  /// </summary>
  public static void ReplaceTextWithText(WordTemplateModel model)
  {
    temp = model;
    string path = HttpContext.Current.Server.MapPath("/") + "/Resource/";//获取服务器地址文档所在地址
    // Load a document.
    using (var document = DocX.Load(path + @"WordTemplate/WordTemplate.docx"))//加载文档
    {
      // Check if some of the replace patterns are used in the loaded document.
      if (document.FindUniqueByPattern(@"<[\w \=]{4,}>", RegexOptions.IgnoreCase).Count > 0)
      {
        // Do the replacement of all the found tags and with green bold strings.根据模板规则,替换文档段落属性值
        document.ReplaceText("<(.*?)>", WordHelper.ReplaceFunc, false, RegexOptions.IgnoreCase);

        // 表格1:填充表1内容
        if (temp.tab1.Count > 0)
        {
          var docTab1 = document.Tables.FirstOrDefault();//读取模板第一个表
          if (docTab1 != null)
          {
            if (docTab1.RowCount > 1)
            {
              var rowPattern = docTab1.Rows[1];//属性行
              int index = 1;
              foreach (var obj in temp.tab1)
              {
                obj.index = index;
                WordHelper.AddItemToTable(docTab1,rowPattern,obj);
                index++;
              }
              rowPattern.Remove();
            }
          }
      }
      // 表格2
      if (temp.tab2.Count > 0)
      {
        var docTab1 = document.Tables[1];
        if (docTab1 != null)
        {
          if (docTab1.RowCount > 1)
          {
            var rowPattern = docTab1.Rows[1];
            int index = 1;
            foreach (var obj in temp.tab2)
            {
              obj.index = index;
              WordHelper.AddItemToTable2(docTab1, rowPattern, obj);
              index++;
            }
            rowPattern.Remove();
          }
        }
      }

      try
      {
        MemoryStream ms = new MemoryStream();//创建内存流
        HttpContext curContext = HttpContext.Current;
        document.SaveAs(ms);//将文档保存到内存流(另外可指定路径存到本地目录,这里要导出下载,所以存到流)
        ms.Flush();
        ms.Position = 0;
        // 添加头信息,为"文件下载/另存为"对话框指定默认文件名
        curContext.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}.docx", "成本费用转换单"));
        curContext.Response.Charset = "UTF-8";
        curContext.Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
        // 指定返回的是一个不能被客户端读取的流,必须被下载
        curContext.Response.ContentType = "application/ms-word";
        // 把文件流发送到客户端
        curContext.Response.BinaryWrite(ms.ToArray());
        curContext.Response.Flush();
        curContext.Response.End();
        ms.Close();
        ms.Dispose();
      }
      catch (Exception ex)
      {
        if (ex is ExceptionEx)
        {
          throw;
        }
        else
        {
          throw ExceptionEx.ThrowBusinessException(ex);
        }
        throw;
      }

    }
  }
}

#region Private Methods

//替换段落属性方法

private static string ReplaceFunc(string findStr)
{
  PropertyInfo property = temp.GetType().GetProperty(findStr);
  if (property != null)
  {
    return property.GetValue(temp, null).ToString();
  }
  return findStr;
}

//替换表格属性方法
private static void AddItemToTable(Table table, Row rowPattern, TableModel1 entity)
{

// Insert a copy of the rowPattern at the last index in the table.
var newItem = table.InsertRow(rowPattern, table.RowCount - 1);

// Replace the default values of the newly inserted row.
newItem.ReplaceText("%attr1%", entity.attr1);
newItem.ReplaceText("%attr2%", entity.attr2);
newItem.ReplaceText("%attr3%", entity.attr3);

}
private static void AddItemToTable2(Table table, Row rowPattern, TableModel2 entity)
{

// Insert a copy of the rowPattern at the last index in the table.
var newItem = table.InsertRow(rowPattern, table.RowCount - 1);

// Replace the default values of the newly inserted row.
newItem.ReplaceText("%attr1%", entity.attr1);
newItem.ReplaceText("%attr2%", entity.attr2);
newItem.ReplaceText("%attr3%", entity.attr3);

}
#endregion
}

三、控制器代码

/// <summary>
/// 导出word
/// <param name="model">数据模型</param>
/// <summary>
/// <returns></returns>
[HttpPost]
public void ExportWord(string model)
{
WordTemplateModel entity = model.ToObject<WordTemplateModel>();//字符串转成对象
WordHelper.ReplaceTextWithText(entity);
}

/// <summary>
/// 字串反序列化成指定对象实体
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="Json">字串</param>
/// <returns></returns>
public static T ToObject<T>(this string Json)
{
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
}

四、前台请求代码

function download(options) {

if (options.url && options.param) {

var $form = $('<form action="' + options.url + '" method="' + (options.method || 'post') + '"></form>');

for (var key in options.param) {
var $input = $('<input type="hidden" data-back="backhr"/>').attr('name', key).val(options.param[key]);
$form.append($input);
}
$form.appendTo('body').submit().remove();
};
}

 

$('#btn_export_word').on('click', function() {
var data = {};
var tab1 = [];
var tab2 = [];
data.title = 'xxx单';
data.tab1 = tab1;
data.tab2 = tab2;

download({ url:  'ExportWord', param: { model: JSON.stringify(data) }, method: 'POST' })

});

五、总结

这里主要实现一个文档数据导出下载功能,按照已经设计好的模板填充内容然后给浏览器下载。工具方面的更多操作不过多讲述。这只是工作中遇到需求功能,在此做个记录。

六、工具学习友情链接

http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_sharp_001_docx1.html(博主:LinuxPanda

posted @ 2020-05-09 17:15  巴泽奇特  阅读(830)  评论(0)    收藏  举报