方法一:使用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的两种方法(超简单)的更多相关文章

  1. 【吉光片羽】MVC 导出Word的两种方式

    1.直接将Html转成Word.MVC自带FileResult很好用.Html中我们也可以嵌入自己的样式. html: <div id="target"> <st ...

  2. .net导出Word的一种方法

    由于ActiveX控件只支持IE(好像FF可以通过安装插件支持),所以js导出word的方式就比较局限 可是如果当页面经过js修改以后,.net是无法获取到的,所以要通过js获取到最新的html并传给 ...

  3. C++ DLL导出函数的两种方法(导出序号那种方法,别人看不到函数名)

    第一种就直接导出函数名如下代码: #ifdef__cplusplus #define TEXPORT extern "c" _declspec(dllexport) #dlse # ...

  4. JavaScript模板引擎artTemplate.js——两种方法实现性别的判定

    template.helper(name, callback) name:必传,辅助事件的名称. callback:必传,辅助事件的回调函数. return:undefined 所谓的辅助事件,主要用 ...

  5. layui导出表格的两种方法

    一.不熟悉layui小白使用方法 1.引入如下js文件: 2.编写如下函数: 3.表格ID要与函数取值保持一致即可,再就是自定义一个按钮触发事件 二.引入插件使用方法 1.layui官网下载插件包: ...

  6. php导出表格两种方法 ——PhpExcel的列子

    php常用的导出表格有两种方法,第一种是输出表格,这种方法打开的时候有警告提示,一般导出表格会用phpexcel,这个导出比较灵活,而且还可以设置表格的样式. 第一种导出例子 /** * 执行导出 * ...

  7. C#通过模板导出Word(文字,表格,图片)

    C#通过模板导出Word(文字,表格,图片)   C#导出Word,Excel的方法有很多,这次因为公司的业务需求,需要导出内容丰富(文字,表格,图片)的报告,以前的方法不好使,所以寻找新的导出方法, ...

  8. 代码操作Word时,目录自动更新的两种方法

    最近的项目中有一个功能点为:根据分析数据库并生成报告.不过不是大数据.数据挖掘之类,报告的内容.组织方式都是事先固定下来的.实现的方式为,在普通word文档中插入书签制成模板,然后程序使用OpenXM ...

  9. AE 将地图导出为图片的两种方法

    在ArcGIS的开发中,我们经常需要将当前地图打印(或是转出)到图片文件中.将Map或Layout中的图象转出有两种方法,一种为通过IActiveView的OutPut函数,另外一种是通过IExpor ...

随机推荐

  1. [前端进阶课] 构建自己的 webpack 知识体系

    webpack webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件. Webpack 核心概念: Entry(入口):Webpack 执 ...

  2. kubernetes pod的弹性伸缩———基于pod自定义custom metrics(容器的IO带宽)的HPA

    背景 ​ 自Kubernetes 1.11版本起,K8s资源采集指标由Resource Metrics API(Metrics Server 实现)和Custom metrics api(Promet ...

  3. 浙工大新生赛莫队处理+区间DP+KMP+分析题

    题目描述 读入一个长度为n的整数数列a1,a2,…,an,以及一个整数K. q组询问. 每组询问包含一个二元组(l, r), 其中1≤l≤r≤ n, 求所有满足以下条件的二元组(l2, r2)的数目: ...

  4. PHP 获取当前目录下的所有文件

    我们有时候会想拿到当前目录下的所有文件名,以下就是我写的一个方法,请大家参考 // 获取当前文件的上级目录 $con = dirname(__FILE__); // 扫描$con目录下的所有文件 $f ...

  5. tp入门

    其中可以配置隐藏看入口文件 和默认读取路径 <?php namespace app\admin\controller; //生命控制器 class Index { public function ...

  6. 用 CSS Grid 布局制作一个响应式柱状图

    最新一段时间比较喜欢玩弄图表,出于好奇,我想找出比较好的用 CSS 制作图表的方案.开始学习网上开源图表库,它对我学习新的和不熟悉的前端技术很有帮助,比如这个:CSS Grid. 今天和大家分享我学到 ...

  7. Spring笔记 - 组件注册

    @Bean:类注入容器 xml方式: <bean id="person" class="com.hrh.bean.Person"> <prop ...

  8. Could not find the Qt platform plugin windows错误解决方法

    在PyCharm中运行PyQt5窗口程序时,出现了下图所有的错误提示. 出现该问题的原因是环境变量没有添加. 解决方法:在环境变量中增加:QT_QPA_PLATFORM_PLUGIN_PATH 路径: ...

  9. Rocket - util - Frequency

    https://mp.weixin.qq.com/s/QoP9Gbm9hUQ4xsjJQ0pZ1Q   简单介绍Frequency的实现.   ​​   一个实例: ​​     1. 基本介绍   ...

  10. JavaScript (二) js的基本语法 - - 运算符、流程控制

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.运算符 1.一元运算符 ++ -- 都是运算符 ++ 和 -- 可以分为:前+ 和后+ and 前- ...