C#通过模板导出Word的两种方法(超简单)
方法一:使用Office的组件
使用该方法必须要安装Office
1、制作Word模板

在需要填充内容的地方增加标识符号,方便之后替换使用,例如 [项目名称],其中[]符号和中间的文字可根据个人情况进行修改。
到此模板已经制作完成,是不是很简单。
2、操作Word
2.1 引用Microsoft.Office.Interop.Word.dll
添加命名空间
using Word = Microsoft.Office.Interop.Word;
2.2 编码开始
string mubanFile = "模板.docx";
string templatePath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, mubanFile);
Dictionary<string, string> bookmarks = new Dictionary<string, string>();
var item=xxx;//数据源
//将数据与Word模板中的标签对应
bookmarks.Add("[姓名]", item.UserName);
bookmarks.Add("[性别]", item.Sex);
bookmarks.Add("[出生年月]", item.BirthDay);
bookmarks.Add("[民族]", item.Ethnic);
bookmarks.Add("[文化程度]", item.EducationalLevel);
bookmarks.Add("[详细地址]", item.Address);
bookmarks.Add("[电话]", item.Phone);
string wordpath = outputPath + "xx.docx";//导出word地址
string pdfpath = outputPath + "xx.pdf";//导出pdf地址
GenerateWord(templatePath, wordpath, pdfpath, bookmarks);
/// <summary>
/// 根据word模板文件导出word/pdf文件
/// </summary>
/// <param name="templateFile">模板路径</param>
/// <param name="fileNameWord">导出文件名称</param>
/// <param name="fileNamePdf">pdf文件名称</param>
/// <param name="bookmarks">模板内书签集合</param>
public static void GenerateWord(string templateFile, string fileNameWord, string fileNamePdf, Dictionary<string, string> bookmarks)
{
Microsoft.Office.Interop.Word.Application app = new Microsoft.Office.Interop.Word.Application();
File.Copy(templateFile, fileNameWord, true);
Microsoft.Office.Interop.Word.Document doc = new Microsoft.Office.Interop.Word.Document();
object Obj_FileName = fileNameWord;
object Visible = false;
object ReadOnly = false;
object missing = System.Reflection.Missing.Value;
object IsSave = true;
object FileName = fileNamePdf;
object FileFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatPDF;
object LockComments = false;
object AddToRecentFiles = true;
object ReadOnlyRecommended = false;
object EmbedTrueTypeFonts = false;
object SaveNativePictureFormat = true;
object SaveFormsData = false;
object SaveAsAOCELetter = false;
object Encoding = Microsoft.Office.Core.MsoEncoding.msoEncodingSimplifiedChineseGB18030;
object InsertLineBreaks = false;
object AllowSubstitutions = false;
object LineEnding = Microsoft.Office.Interop.Word.WdLineEndingType.wdCRLF;
object AddBiDiMarks = false;
try
{
doc = app.Documents.Open(ref Obj_FileName, ref missing, ref ReadOnly, ref missing, ref missing, ref missing, ref missing,
ref missing, ref missing, ref missing, ref missing, ref Visible, ref missing, ref missing, ref missing, ref missing);
doc.Activate();
foreach (string bookmarkName in bookmarks.Keys)
{
string newstr;
string newStrs;
replace(doc, bookmarkName, bookmarks[bookmarkName]);//替换内容
}
//replace(doc, "hello", "shalv");
//此处存储时,参数可选填,如需另外生成pdf,加入一个参数ref FileName,
doc.SaveAs(ref FileName, ref FileFormat, ref LockComments,
ref missing, ref AddToRecentFiles, ref missing,
ref ReadOnlyRecommended, ref EmbedTrueTypeFonts,
ref SaveNativePictureFormat, ref SaveFormsData,
ref SaveAsAOCELetter, ref Encoding, ref InsertLineBreaks,
ref AllowSubstitutions, ref LineEnding, ref AddBiDiMarks);
doc.Close(ref IsSave, ref missing, ref missing);
}
catch (Exception ex)
{
LogHelper.WriteLog(ex.ToString());
doc.Close(ref IsSave, ref missing, ref missing);
}
}
///<summary>
/// 在word 中查找一个字符串直接替换所需要的文本
/// </summary>
/// <param name="strOldText">原文本</param>
/// <param name="strNewText">新文本</param>
/// <returns></returns>
public static void replace(Microsoft.Office.Interop.Word.Document doc, string strOldText, string strNewText)
{
doc.Content.Find.Text = strOldText;
object FindText, ReplaceWith, Replace;//
object MissingValue = Type.Missing;
FindText = strOldText;//要查找的文本
ReplaceWith = strNewText;//替换文本
Replace = Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll;
/*wdReplaceAll - 替换找到的所有项。
* wdReplaceNone - 不替换找到的任何项。
* wdReplaceOne - 替换找到的第一项。
* */
doc.Content.Find.ClearFormatting();//移除Find的搜索文本和段落格式设置
doc.Content.Find.Execute(
ref FindText, ref MissingValue,
ref MissingValue, ref MissingValue,
ref MissingValue, ref MissingValue,
ref MissingValue, ref MissingValue, ref MissingValue,
ref ReplaceWith, ref Replace,
ref MissingValue, ref MissingValue,
ref MissingValue, ref MissingValue);
}
好了,到这就完成了。
不过有个小问题,这种替换的方式,当要替换的字符串超过一定的长度,就会提示“字符串参量过长”,搜索发现,替换的最大长度为255字符。
下面是解决方法
在替换前判断替换内容长度是否超过255,如果超长就分段替换,代码如下
foreach (string bookmarkName in bookmarks.Keys)
{
int len = bookmarks[bookmarkName].Length;
int cnt = len / 255;
string newstr;
string newStrs;
if (bookmarks[bookmarkName].Length < 255)
{
replace(doc, bookmarkName, bookmarks[bookmarkName]);//替换内容
}
else
{
for (int i = 0; i <= cnt; i++)
{
if (i != cnt)
newstr = bookmarks[bookmarkName].ToString().Substring(i * 255, 255) + bookmarkName; //新的替换字符串
else
newstr = bookmarks[bookmarkName].ToString().Substring(i * 255, len - i * 255); //最后一段需要替换的文字
newStrs = newstr;
replace(doc, bookmarkName, newStrs);//替换内容
}
}
}
第一种方法搞定!!!
方法二:使用Aspose.Words
这种方法不用安装office。
1、制作模板
在需要替换的地方插入域,插入-》文档部件-》域-》选择MergeField,在域名处添加内容。
WPS的步骤为 插入-》选择文档部件-》选择域-》选择邮件合并

添加完成后的效果如下:

2、上代码
2.1 添加引用
using Aspose.Words;
2.1 建立对应关系
string[] fieldNames = new string[] { "姓名", "性别", "出生年月", "民族", "文化程度", "详细地址", "电话" };
object[] fieldValues = new object[] { item.Name, item.Sex, item.BirthDay, item.Ethnic, item.EducationalLevel, item.Address, item.Phone};
string mubanFile = "模板1.docx";
string templatePath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, mubanFile);
string wordpath = outputPath + "xx.docx";//导出word地址
AsposeWordHelper helper = new AsposeWordHelper();
helper.OpenTempelte(templatePath); //打开模板文件
helper.Executefield(fieldNames, fieldValues);//域赋值
helper.SaveDoc(wordpath); //文件保存
下面是word文档操作辅助类AsposeWordHelper.cs的内容
/// <summary>
/// word文档操作辅助类
/// </summary>
public class AsposeWordHelper
{
/// <summary>
/// Word
/// </summary>
private Document wordDoc;
/// <summary>
/// 基于模版新建Word文件
/// </summary>
/// <param name="path">模板路径</param>
public void OpenTempelte(string path)
{
wordDoc = new Document(path);
}
/// <summary>
/// 书签赋值用法
/// </summary>
/// <param name="LabelId">书签名</param>
/// <param name="Content">内容</param>
public void WriteBookMark(string LabelId, string Content)
{
if (wordDoc.Range.Bookmarks[LabelId] != null)
{
wordDoc.Range.Bookmarks[LabelId].Text = Content;
}
}
/// <summary>
/// 列表赋值用法
/// </summary>
/// <param name="dt"></param>
public void WriteTable(DataTable dt)
{
wordDoc.MailMerge.ExecuteWithRegions(dt);
}
/// <summary>
/// 文本域赋值用法
/// </summary>
/// <param name="fieldNames">key</param>
/// <param name="fieldValues">value</param>
public void Executefield(string[] fieldNames, object[] fieldValues)
{
wordDoc.MailMerge.Execute(fieldNames, fieldValues);
}
/// <summary>
/// Pdf文件保存
/// </summary>
/// <param name="filename">文件路径+文件名</param>
public void SavePdf(string filename)
{
wordDoc.Save(filename, SaveFormat.Pdf);
}
/// <summary>
/// Doc文件保存
/// </summary>
/// <param name="filename">文件路径+文件名</param>
public void SaveDoc(string filename)
{
wordDoc.Save(filename, SaveFormat.Doc);
}
/// <summary>
/// 不可编辑受保护,需输入密码
/// </summary>
/// <param name="pwd">密码</param>
public void NoEdit(string pwd)
{
wordDoc.Protect(ProtectionType.ReadOnly, pwd);
}
/// <summary>
/// 只读
/// </summary>
public void ReadOnly()
{
wordDoc.Protect(ProtectionType.ReadOnly);
}
/// <summary>
/// 通过流导出word文件
/// </summary>
/// <param name="stream">流</param>
/// <param name="fileName">文件名</param>
public static HttpResponseMessage ExportWord(Stream stream, string fileName)
{
var file = stream;
fileName += DateTime.Now.ToString("yyyyMMddHHmmss");
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(file);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/msword");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = fileName + ".doc";
return result;
}
/// <summary>
/// 通过流导出pdf文件
/// </summary>
/// <param name="stream">流</param>
/// <param name="fileName">文件名</param>
public static HttpResponseMessage ExportPdf(Stream stream, string fileName)
{
var file = stream;
fileName += DateTime.Now.ToString("yyyyMMddHHmmss");
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StreamContent(file);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/pdf");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
result.Content.Headers.ContentDisposition.FileName = fileName + ".pdf";
return result;
}
这种方法虽然不用安装office,但是导出的文档有AsposeWord的水印和页眉,不过可以手动去掉。
大家有没有其他的方法,欢迎讨论。
如有错误,还请批评指正!
C#通过模板导出Word的两种方法(超简单)的更多相关文章
- 【吉光片羽】MVC 导出Word的两种方式
1.直接将Html转成Word.MVC自带FileResult很好用.Html中我们也可以嵌入自己的样式. html: <div id="target"> <st ...
- .net导出Word的一种方法
由于ActiveX控件只支持IE(好像FF可以通过安装插件支持),所以js导出word的方式就比较局限 可是如果当页面经过js修改以后,.net是无法获取到的,所以要通过js获取到最新的html并传给 ...
- C++ DLL导出函数的两种方法(导出序号那种方法,别人看不到函数名)
第一种就直接导出函数名如下代码: #ifdef__cplusplus #define TEXPORT extern "c" _declspec(dllexport) #dlse # ...
- JavaScript模板引擎artTemplate.js——两种方法实现性别的判定
template.helper(name, callback) name:必传,辅助事件的名称. callback:必传,辅助事件的回调函数. return:undefined 所谓的辅助事件,主要用 ...
- layui导出表格的两种方法
一.不熟悉layui小白使用方法 1.引入如下js文件: 2.编写如下函数: 3.表格ID要与函数取值保持一致即可,再就是自定义一个按钮触发事件 二.引入插件使用方法 1.layui官网下载插件包: ...
- php导出表格两种方法 ——PhpExcel的列子
php常用的导出表格有两种方法,第一种是输出表格,这种方法打开的时候有警告提示,一般导出表格会用phpexcel,这个导出比较灵活,而且还可以设置表格的样式. 第一种导出例子 /** * 执行导出 * ...
- C#通过模板导出Word(文字,表格,图片)
C#通过模板导出Word(文字,表格,图片) C#导出Word,Excel的方法有很多,这次因为公司的业务需求,需要导出内容丰富(文字,表格,图片)的报告,以前的方法不好使,所以寻找新的导出方法, ...
- 代码操作Word时,目录自动更新的两种方法
最近的项目中有一个功能点为:根据分析数据库并生成报告.不过不是大数据.数据挖掘之类,报告的内容.组织方式都是事先固定下来的.实现的方式为,在普通word文档中插入书签制成模板,然后程序使用OpenXM ...
- AE 将地图导出为图片的两种方法
在ArcGIS的开发中,我们经常需要将当前地图打印(或是转出)到图片文件中.将Map或Layout中的图象转出有两种方法,一种为通过IActiveView的OutPut函数,另外一种是通过IExpor ...
随机推荐
- 微信小程序var和let以及const有什么区别
微信小程序var和let以及const的区别: 在JavaScript中有三种声明变量的方式:var.let.const. var:声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循 ...
- centos7 git下载速度慢
nslookup命令 yum -y install bind-utils [root@iZ1i4qd6oynml0Z ~]# nslookup github.global.ssl.fastly.Net ...
- 3.1Go变量
3.1 Go变量 变量是对内存中数据存储空间的表示,如同门牌号对应着房间,同样的,变量名字对应变量的值. 变量:本质就是一块内存空间.用于存储某个数值.该数值在运行时可以改变. 变量使用步骤 1.声明 ...
- 苏浪浪 201771010120 《面向对象程序设计(java)》第9周学习总结
实验九异常.断言与日志 实验时间 2018-10-25 1.实验目的与要求 (1) 掌握java异常处理技术: (2) 了解断言的用法: (3) 了解日志的用途: (4) 掌握程序基础调试技巧: 2. ...
- Fabric CA的部署与使用
Fabric CA是Hyperledger Fbric的证书认证中心,提供以下功能:用户信息的登记与注册,数字证书的颁发与管理. 前言 之前使用CA服务一直是在docker容器中运行下载好的CA镜像, ...
- UVALive 3295
题目大意:见刘汝佳<算法竞赛入门经典——训练指南>P173 解题思路: 每一个合法的三角形的三个顶点都不在同一直线上,那么问题其实就是在求所有不全在同一直线上的三点的组合数. 我们可以利用 ...
- centos7 安装rpm版的mysql遇到坑——误删root用户的恢复
在网上找了教程http://blog.csdn.net/frankcheng5143/article/details/77609093安装过程很顺利,随着修改了root的密码后不下心误删了root账号 ...
- 关于lua的那些事
1.lua是一个脚本语言,由巴西里约热内卢天主教大学Roberto Ierusalimschy.Waldemar Celes 和 Luiz Henrique de Figueiredo三人所组成的研究 ...
- vue-cli3区分开发和生产环境
vue-cli3出来很久了,之前一直使用vue-cli2的配置,并且区分了生产和开发环境,自己的理解,环境分两大类,开发环境 和生产环境,最近升级到了vue-cli4当然改动并不大. 升级的主要原因嘛 ...
- Android调试非常有用的命令集1_adb&aapt&git&repo&scp&while
Linux部分场景非常有用的命令集_1_持续更新 这里面也包含了对于开发调试有用的命令,也可以看看. 这里不做详细说明或截图,仅作为记录和简单说明.注:可能只针对某一命令部分功能,不包含整个功能,若要 ...