Word书签不但可以帮助读者快速跳转到想要查看的位置,而且可以用做“占位符”,程序员获取“占位符”之后,就可以更新这些“占位符”,即替换书签内容。替换模板文档中的书签内容,可以帮助我们快速生成Word报表或文档。
本文总结了一个将常见的Word文档元素(文字、图片和表格)替换进书签的C#解决方案,具体步骤见下文。
使用工具:
- Spire.Doc.dll 6.4.5
- Visual Studio 2013
步骤一 制作模板
1. 新建Word文档
\
图1 创建文档
2. 插入书签
\
图2 插入书签
3. 保存模板,命名为“bookmark_template.docx”
\
图3 保存模板文档
步骤二 在项目中添加引用
1. 右键点击“解决方案资源管理”中的“引用”,选择“添加引用”
\
图4 添加引用
2. 选择要引用的Spire.Doc.dll文件,添加至项目中
\
图5 引用Spire.Doc.dll
步骤三 编码
Spire.Doc提供了BookmarksNavigator类来获取和操作文档中的书签,但方法不是很直观。为了方便,我自己封装了Bookmark类,其中包括RepalceContent及其2个重载方法来分别应对插入文字、图片和表格三种情况。
- public TextRange ReplaceContent(string bookmarkName, string text, bool saveFormatting)
- public void ReplaceContent(string bookmarkName, string picPath, float widthScale, float heightScale, TextWrappingStyle wrapStyle, ShapeHorizontalAlignment horizontalAlignment)
- public void ReplaceContent(string bookmarkName, Table table)
第一部分:Bookmark.cs编码
using Spire.Doc;
using Spire.Doc.Fields;
using System.Drawing;
using Spire.Doc.Interface;
using Spire.Doc.Documents;
namespace ReplaceBookmarkContent
{
class Bookmark
{
private Document doc = null;
public Bookmark(Document document)
{
doc = document;
}
/// <summary>
/// 用文本替换指定书签的内容
/// </summary>
/// <param name="bookmarkName">书签名</param>
/// <param name="text">文本</param>
/// <param name="saveFormatting">删除原始书签内容时,是否保留格式</param>
/// <returns>TextRange</returns>
public TextRange ReplaceContent(string bookmarkName, string text, bool saveFormatting)
{
BookmarksNavigator navigator = new BookmarksNavigator(doc);
navigator.MoveToBookmark(bookmarkName);//指向特定书签
navigator.DeleteBookmarkContent(saveFormatting);//删除原有书签内容
Spire.Doc.Interface.ITextRange textRange = navigator.InsertText(text);//写入文本
return textRange as TextRange;
}
/// <summary>
/// 用图片替换指定书签的内容
/// </summary>
/// <param name="bookmarkName">书签名</param>
/// <param name="picPath">图片路径</param>
/// <param name="widthScale">宽度缩放比例,0以上正整数</param>
/// <param name="heightScale">高度缩放比例,0以上正整数</param>
/// <param name="wrapStyle">环绕方式</param>
/// <param name="horizontalAlignment"></param>
public void ReplaceContent(string bookmarkName, string picPath, float widthScale, float heightScale, TextWrappingStyle wrapStyle, ShapeHorizontalAlignment horizontalAlignment)
{
BookmarksNavigator navigator = new BookmarksNavigator(doc);
navigator.MoveToBookmark(bookmarkName);
navigator.DeleteBookmarkContent(false);
IParagraphBase paragraphBase = navigator.InsertParagraphItem(ParagraphItemType.Picture);//插入类型为图片
Image image = Image.FromFile(picPath);//加载图片
DocPicture picture = paragraphBase.OwnerParagraph.AppendPicture(image);//插入图片
picture.WidthScale = widthScale;
picture.HeightScale = heightScale;
picture.TextWrappingStyle = wrapStyle;
picture.HorizontalAlignment = horizontalAlignment;
}
/// <summary>
/// 用表格替换指定书签的内容
/// </summary>
/// <param name="bookmarkName">书签名</param>
/// <param name="table">Table实例</param>
public void ReplaceContent(string bookmarkName, Table table)
{
BookmarksNavigator navigator = new BookmarksNavigator(doc);
navigator.MoveToBookmark(bookmarkName);
TextBodyPart body = new TextBodyPart(doc);
body.BodyItems.Add(table);
navigator.ReplaceBookmarkContent(body);
}
/// <summary>
/// 创建表格并写入数据,返回Table对象
/// </summary>
/// <param name="rowsNum">行数</param>
/// <param name="columnsNum">列数</param>
/// <param name="columnWidth">列宽</param>
/// <param name="horizontalAlignment">水平对齐方式</param>
/// <param name="datatable">DataTable实例</param>
/// <returns></returns>
public Table CreateTable(int rowsNum, int columnsNum, float columnWidth, RowAlignment horizontalAlignment, System.Data.DataTable datatable)
{
Table table = new Table(doc, true, 1f);//初始化Table对象
table.ResetCells(rowsNum, columnsNum);//设置行数和列数
//填充数据
for (int i = 0; i < datatable.Rows.Count; i++)
{
for (int j = 0; j < datatable.Columns.Count; j++)
{
table.Rows[i].Cells[j].AddParagraph().AppendText(datatable.Rows[i][j].ToString());
}
}
//设置列宽
for (int i = 0; i < rowsNum; i++)
{
for (int j = 0; j < columnsNum; j++)
{
table.Rows[i].Cells[j].Width = columnWidth;
}
}
table.TableFormat.HorizontalAlignment = horizontalAlignment;//表格水平对齐方式
return table;
}
}
}
第二步部分:生成文件的编码
//加载模板文档
Document doc = new Document();
doc.LoadFromFile(@"C:\Users\Administrator\Desktop\bookmark_template.docx");
//初始化Bookmark对象
Bookmark bookmark = new Bookmark(doc);
//用文本替换书签bookmark_text的内容
string text = "XXX科技股份有限公司成立于2010年12月,是一家致力于高新技术产品研发、生产、销售的高科技股份制企业,"
+ "公司坚持以技术创新为核心,以知识产权为基础,以人才战略为支撑,经过多年的砺练与发展,公司已逐步成以创新为引导的,"
+ "产品具有竞争力,人才素质优良的新兴科技企业。";
bookmark.ReplaceContent("bookmark_text", text, true);
//用图片替换书签bookmark_picture的内容
string picPath = @"C:\Users\Administrator\Desktop\company_logo.jpg";
bookmark.ReplaceContent("bookmark_picture", picPath, 80f, 80f, TextWrappingStyle.TopAndBottom, ShapeHorizontalAlignment.Center);
//创建模拟数据
DataTable dt = new DataTable();
dt.Columns.Add("employee_id", typeof(string));
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("age", typeof(string));
dt.Columns.Add("sex", typeof(string));
dt.Columns.Add("title", typeof(string));
dt.Rows.Add(new string[] {"工号", "姓名", "年龄", "性别", "职位" });
dt.Rows.Add(new string[] {"1023","Nancy", "28", "女", "Java程序员" });
dt.Rows.Add(new string[] { "1024","James", "34", "男", ".NET程序员" });
dt.Rows.Add(new string[] { "1025","Kobe", "38", "男", "系统管理员" });
//创建表格,并填充数据
Table table = bookmark.CreateTable(dt.Rows.Count, dt.Columns.Count, 100f, RowAlignment.Left, dt);
//用表格替换书签bookmark_table的内容
bookmark.ReplaceContent("bookmark_table", table);
//生成Word文件
doc.SaveToFile("output.docx", FileFormat.Docx2013);
运行代码,得到下面的结果:
\
图6 生成的文件\
注:
1. Spire.Doc本身也有Bookmark类,但仅用于添加书签到文档中,请注意本文中的Bookmark类是自定义的方便自己使用的方法的集合。
2. Spire.Doc 6.4.5 为商业版,在不应用许可证的情况下,生成的文档会有水印信息。笔者写文章时已应用临时许可证(官方提供的用于测试软件的License)。
3. 笔者使用免费版的Spire.Doc测试过,以上效果基本都能实现,但图片的环绕方式只能设置为“InLine”,且水平位置为靠右,设置其他环绕方式时,图片位置会出错。这应该是免费版的Bug。
(原创内容,转载请注明出处)