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 ...
随机推荐
- 如何使用Postman生成不同格式测试的报告
Postman还可以生成测试报告,还是多种格式报告? Postman团队开源Newman作为Postman运营工具,该开源库使用命令行方式执行Postman 脚本,并且生成多种格式报告,还支持Post ...
- Jenkins-gogs安装及使用
很多同学可能第一次了解什么是ci-cd,什么是Jenkins,首先会介绍下cicd的概念及应用场景,之后再详细介绍下Jenkins的概念.安装及使用. 什么是CI-CD? 首先明确CI-CD是一种技术 ...
- Kafka SSL安装与配置
1.概述 最近有同学咨询说,Kafka的SSL安全认证如何安装与使用?今天笔者将通过以下几个方面来介绍Kafka的SSL: Kafka 权限介绍 Kafka SSL的安装与使用 Kafka Eagle ...
- js-实现多列布局(瀑布流)
本文是使用面向对象的思想实现多列布局(瀑布流).当然,使用面向过程也能实现,具体效果图和案例如下: 具体实现代码如下: <!DOCTYPE html> <html lang=&quo ...
- Vue 更换页面图标和title
1.基础的做法就是直接换掉,logo换的时候需要使用icon格式的图标 title 直接在index.html 里面把原来的title注释掉 或者直接改了就行 2. 如果需要进行相应的改变啥的 ,需要 ...
- Consul+upsync+Nginx实现动态负载均衡
上一篇文章 <C# HttpClient 使用 Consul 发现服务> 解决了内部服务之间的调用问题, 对外提供网关服务还没有解决, 最后我选择了 nginx-upsync-module ...
- ATX-UI自动化环境搭建
基础环境准备(以下都是在Mac机上搭建的) 1.android sdk安装&配置 很完美的一个资源下载网:tools.android-studio.org,下载所需的包(我下的zip包直接解压 ...
- APP定位元素之UiSelector
1.UiSelector 类介绍 功能:通过各种属性与节点关系定位组件 操作步骤:找到对象->操作对象 2.四中匹配关系的介绍 (1)完全匹配 (2)包含匹配 (3)正则匹配 (4)起始匹 例子 ...
- 关于Tensorflow基于Windows安装那些事儿
声明:代码及博客小白一枚,如有错误,感谢指正~~ 众所周知,摘抄来温习一遍: Tensorflow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库.节点(Nodes) ...
- MVC案例之模糊查询与删除
查询操作: Servlet //1. 调用 CustomerDAO 的 getAll() 得到 Customer 的集合 List<Customer> customers ...