把数据输出到Word (组件形式)
上一篇的文章中我们介绍了在不使用第三方组件的方式,多种数据输出出到 word的方式,最后我们也提到了不使用组件的弊端,就是复杂的word我们要提前设置模板、编码不易控制、循环输出数据更是难以控制。接下来介绍用第三方组件Aspose.Words 的开发方式解决上面提到的问题。
[本次实例和上次实例的源代码,点击这里下载]
[Aspose.Words.dll 以及 使用手册由于太大传到csdn上了,点这里下载(免费)]
文章的梗概:
♦ 整体概括
♦ 支持的平台
♦ 支持的文件格式
♦ 保存word文档
♦ 创建书签
♦ 控制文字输出样式
♦ 输出表格
♦ 综合实例介绍
♦ 运用书签输出表格
一、Aspose.Words 的介绍(更多介绍请到官网查看)
整体概括
An overview of the main conversion, rendering and reporting capabilities of Aspose.Words for .NET.
Aspose.Words在.NET版本下,其渲染和报告能力的主要转换的概述。
Supported Platforms
Aspose.Words for .NET supports the .NET framework (including C#, VB.NET, ASP.NET etc.), ASP, ColdFusion, Perl, Power Builder, PHP, Python and Mono.
Aspose.Words 在 .NET的版本支持.NET framework(包括C#, VB.NET, ASP.NET 等), ASP, ColdFusion, Perl, Power Builder, PHP, Python and Mono.
Supported File Formats
Aspose.Words for .NET supports the popular word (DOC, DOT, DOCM, DOTM, DOCX, DOTX, FlatOpc, FlatOpcMacroEnabled, FlatOpcTemplate, FlatOpcTemplateMacroEnabled, XML, ODT, OTT, OOXML, WordML, RTF, HTML, XHTML, MHTML & TXT) file formats that your business depend on. It also allows exporting or converting word documents to PDF, XPS, XamlFixed, XamlFlow, XamlFlowPack, EPUB, HTML, HtmlFixed, OpenXPS, PostScript, TXT and popular image/multimedia file formats including TIFF, JPG, PNG, BMP, SVG, EMF, SVG and SWF.
Aspose.Words 在 .NET的版本 支持主流的 word文件格式(DOC, DOT, DOCM, DOTM, DOCX, DOTX, FlatOpc, FlatOpcMacroEnabled, FlatOpcTemplate, FlatOpcTemplateMacroEnabled, XML, ODT, OTT, OOXML, WordML, RTF, HTML, XHTML, MHTML & TXT)。它也允许导出或者转换word文档到PDF, XPS, XamlFixed, XamlFlow, XamlFlowPack, EPUB, HTML, HtmlFixed, OpenXPS, PostScript, TXT和主流的文件或TIFF, JPG, PNG, BMP, SVG, EMF, SVG and SWF多媒体格式。
二、Aspose.Words 的基本使用介绍(更多的使用介绍请下载实例,参考使用说明文档或者点这里参考在线版使用文档)
下面的内容是介绍把数据输出到word的常用用法,而word怎么转换成pdf或者其他功能这篇文章将不做介绍,感兴趣可以参考使用文档。
首先我们要添加引用,找到"Aspose.Words.dll"组件的路径,添加此引用到项目中。
其中两个非常重要的对象,Document是文档对象,一切的word控制Document对象时最基础的。另一个就是DocumentBuilder对象,几乎所有的输出类型都是和它有关联。
1 protected void CreateWord_Click(object sender, EventArgs e) 2 { 3 // 实例化 Aspose.Words.Document 对象 4 Document doc = new Document(); 5 6 // 实例化 Aspose.Words.DocumentBuilder 对象 (后面几乎都是通过操作DocumentBuilder实现输出word内容的 7 DocumentBuilder builder = new DocumentBuilder(doc); 8 9 // 往word中输入内容 10 builder.Writeln("这是创建的一个word文档"); 11 12 // 保存到指定的路径 13 doc.Save("G:/CreateWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"); 14 }
可以直接加载项目中对应的word文件
1 protected void LoadWord_Click(object sender, EventArgs e) 2 { 3 // 找到项目中的word模板 并转换成物理路径 4 var path = Server.MapPath("../Document/AsposeWord.doc"); 5 6 // 实例化 Aspose.Words.Document 对象 7 Document doc = new Document(path); 8 9 // 实例化 Aspose.Words.DocumentBuilder 对象 (后面几乎都是通过操作DocumentBuilder实现输出word内容的 10 DocumentBuilder builder = new DocumentBuilder(doc); 11 12 // 往word中输入内容 13 builder.Writeln("这是加载的word文档"); 14 15 // 保存到指定的路径 16 doc.Save("G:/LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"); 17 }
或者把word文件转换成流的形式加载(相比之下上面那种形式用的更多)
1 protected void LoadWord_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/AsposeWord.doc"); 4 5 // 把文件转换成流的形式 6 Stream stream = File.OpenRead(path); 7 8 Document doc = new Document(stream); 9 10 // 用完关闭 11 stream.Close(); 12 13 DocumentBuilder builder = new DocumentBuilder(doc); 14 15 // 往word中输入内容 16 builder.Writeln("这是加载的word文档"); 17 18 // 保存到指定的路径 19 doc.Save("G:/LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"); 20 }
上面的word示例保存是服务器端指定的路径,其实不一定把word保存到指定的路径上,也可以直接把文件保存到客户端,即用户通过类似下载的形式保存。
参数中SaveFormat枚举是指保存的格式,有很多种,这里指定为word的doc格式;SaveType枚举指定保存类型,有SaveType.OpenInWord和OpenInBrowser两种,
如果保存方式指定为OpenInWord会在浏览器左下角提示word文档,而如果是OpenInBrowser会提示打来word文档。当然浏览器的不同,提示的信息也不一样。
1 protected void LoadWord_Click(object sender, EventArgs e) 2 { 3 // 找到项目中的word模板 并转换成物理路径 4 var path = Server.MapPath("../Document/AsposeWord.doc"); 5 6 // 实例化 Aspose.Words.Document 对象 7 Document doc = new Document(path); 8 9 // 实例化 Aspose.Words.DocumentBuilder 对象 (后面几乎都是通过操作DocumentBuilder实现输出word内容的 10 DocumentBuilder builder = new DocumentBuilder(doc); 11 12 // 往word中输入内容 13 builder.Writeln("这是加载的word文档"); 14 15 // 文件保存到客户端 16 var fileName = "LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 17 18 // 保存到客户端(保存的路径默认是客户端自己设置的下载路径,与服务器端无关) 19 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInWord, Response); 20 //doc.Save("G:/LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"); 21 }
可以控制初始显示的大小比例或者打开呈现的形式。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void LoadWord_Click(object sender, EventArgs e) 2 { 3 // 找到项目中的word模板 并转换成物理路径 4 var path = Server.MapPath("../Document/AsposeWord.doc"); 5 6 // 实例化 Aspose.Words.Document 对象 7 Document doc = new Document(path); 8 9 // 实例化 Aspose.Words.DocumentBuilder 对象 (后面几乎都是通过操作DocumentBuilder实现输出word内容的 10 DocumentBuilder builder = new DocumentBuilder(doc); 11 12 // 控制显示的形式 13 doc.ViewOptions.ViewType = ViewType.PageLayout; 14 15 // 控制显示的大小比例此处为百分比,范围是0~100 16 doc.ViewOptions.ZoomPercent = 100; 17 18 19 // 往word中输入内容 20 builder.Writeln("这是加载的word文档"); 21 22 // 文件保存到客户端 23 var fileName = "LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 24 25 // 保存到客户端 26 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 27 //doc.Save("G:/LoadWord(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"); 28 }
创建书签的含义,就和通过我的创建书签一样,到时候就可以快速的定位了。不过一般都是先通过word创建好书签,程序中就可以直接定位到书签的位置,并输出内容。
通过word创建书签:
用程序创建书签(一般都是先通过word创建书签,此处只是演示程序如何创建书签)
1 Document doc = new Document(); 2 DocumentBuilder builder = new DocumentBuilder(doc); 3 // 创建书签 4 builder.StartBookmark("MyBookmark"); 5 6 builder.Writeln("Text inside a bookmark."); 7 // 结束书签 8 builder.EndBookmark("MyBookmark");
前面也说了DocumentBuilder对象,非常强大。原文是这样说的:
DocumentBuilder is a powerful class that is associated with a Document and allows dynamic document building from scratch or the addition of new elements to an existing document. It provides methods to insert text, paragraphs, lists, tables, images and other contents, specification of font, paragraph, and section formatting, and other things. Using DocumentBuilder is somewhat similar in concept to using the StringBuilder class of the .NET Framework.
DocumentBuilder是一个功能强大的类,与文档相关联的,允许动态文档建设从无到有或新的元素到一个现有的文件添加。它提供了方法来插入文字,段落,列表,表格,图片和其他内容,字体,段落格式规范,节,和其他的东西。使用DocumentBuilder有些类似的概念使用的StringBuilder类。NET框架。
当然了由于篇幅问题DocumentBuilder不能详细介绍了,更多细节还是参考说明文档吧。下面回归到文字输出控制的介绍:
1 protected void CreateWordContainFontStyle_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/AsposeWord.doc"); 4 Document doc = new Document(path); 5 DocumentBuilder builder = new DocumentBuilder(doc); 6 7 Aspose.Words.Font font = builder.Font; 8 font.Size = 16; 9 font.Bold = true; 10 font.Color = Color.Blue; 11 font.Name = "Arial"; 12 font.Underline = Underline.Dash; 13 builder.Write("文字样式控制"); 14 15 var fileName = "CreateWordContainFontStyle(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 16 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 17 }
效果如下:
就和上篇文章差不多,利用占位符将我们要输出的内容替换掉。
下面演示中,定义了两个占位符 {name} 和{city}。当然不一定都是用'{}'符号包裹,只要不影响到word中其他内容用什么都可以,最好用特殊点的符号。
word如下:
1 protected void ReplaceFlag_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/AsposeWord2.doc"); 4 Document doc = new Document(path); 5 DocumentBuilder builder = new DocumentBuilder(doc); 6 7 doc.Range.Replace("{name}", "Little-Ant", false, false); 8 doc.Range.Replace("{city}", "上海,徐汇", false, false); 9 10 var fileName = "ReplaceFlag(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 11 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 12 }
效果如下:
在Aspose.Words.Drawing命名空间下有一个Shape对象,通过控制这个对象可以输出类似水印的效果。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void WaterMark_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/AsposeWord2.doc"); 4 Document doc = new Document(path); 5 DocumentBuilder builder = new DocumentBuilder(doc); 6 7 doc.Range.Replace("{name}", "Little-Ant", false, false); 8 doc.Range.Replace("{city}", "上海,徐汇", false, false); 9 10 // 添加水印 11 InsertWatermarkText(doc, "http://www.cnblogs.com/littleAnt-strongPower/"); 12 13 var fileName = "WaterMark(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 14 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 15 } 16 #region 1.5.1 添加水印 17 18 public void InsertWatermarkText(Document doc, string watermarkText) 19 { 20 // Create a watermark shape. This will be a WordArt shape. 21 // You are free to try other shape types as watermarks. 22 Shape watermark = new Shape(doc, ShapeType.TextPlainText); 23 // Set up the text of the watermark. 24 watermark.TextPath.Text = watermarkText; 25 watermark.TextPath.FontFamily = "Arial"; 26 27 // 控制水印的大小 28 watermark.Width = 500; 29 watermark.Height = 60; 30 31 // 倾斜度 32 watermark.Rotation = -15; 33 34 // Remove the following two lines if you need a solid black text. 35 // 控制水印的颜色 36 watermark.Fill.Color = Color.Gray; // Try LightGray to get more Word-style watermark 37 watermark.StrokeColor = Color.Gray; // Try LightGray to get more Word-style watermark 38 39 // 水平居中 40 watermark.RelativeHorizontalPosition = RelativeHorizontalPosition.Page; 41 42 // 垂直居中 注释后会在word正文的头部显示 43 //watermark.RelativeVerticalPosition = RelativeVerticalPosition.Page; 44 45 watermark.WrapType = WrapType.None; 46 47 // 文字的居中方式 48 watermark.VerticalAlignment = VerticalAlignment.Center; 49 watermark.HorizontalAlignment = HorizontalAlignment.Center; 50 51 // Create a new paragraph and append the watermark to this paragraph. 52 53 Paragraph watermarkPara = new Paragraph(doc); 54 55 watermarkPara.AppendChild(watermark); 56 57 // Insert the watermark into all headers of each document section. 58 59 foreach (Section sect in doc.Sections) 60 { 61 // There could be up to three different headers in each section, since we want 62 // the watermark to appear on all pages, insert into all headers. 63 InsertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HeaderPrimary); 64 InsertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HeaderFirst); 65 InsertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HeaderEven); 66 } 67 } 68 69 public void InsertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, HeaderFooterType headerType) 70 { 71 HeaderFooter header = sect.HeadersFooters[headerType]; 72 if (header == null) 73 { 74 // There is no header of the specified type in the current section, create it. 75 header = new HeaderFooter(sect.Document, headerType); 76 sect.HeadersFooters.Add(header); 77 } 78 // Insert a clone of the watermark into the header. 79 header.AppendChild(watermarkPara.Clone(true)); 80 } 81 82 #endregion
效果如下:
这部分是重点,因为需求中经常会牵扯到输出表格的需求。输出表格的原理,就是先设置好表格的样式,然后"画"出来。实例中演示画一个含有表头5行4列的表格。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void OutPutTable_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/AsposeWord.doc"); 4 Document doc = new Document(path); 5 DocumentBuilder builder = new DocumentBuilder(doc); 6 7 Aspose.Words.Font font = builder.Font; 8 font.Bold = false; 9 font.Size = 12; 10 11 // 设置表格的样式 12 builder.RowFormat.Borders.LineStyle = LineStyle.Single; 13 builder.RowFormat.HeightRule = HeightRule.Exactly; 14 builder.RowFormat.Alignment = RowAlignment.Center; 15 // 设置行高 16 builder.RowFormat.Height = 24; // 设置单元格的高度 17 18 // 表格设置为4列 总宽度为492.7 19 double width1 = 92.7; 20 double width2 = 100; 21 double width3 = 150; 22 double width4 = 150; 23 24 // 设置每个单元格内的样式 25 builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; 26 builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; 27 builder.CellFormat.VerticalMerge = CellMerge.First; 28 builder.CellFormat.HorizontalMerge = CellMerge.None; 29 30 // 开始画单元格 31 builder.InsertCell(); 32 // 设置单元格的宽度 33 builder.CellFormat.Width = width1; 34 // 单元格中的内容 35 builder.Write("姓名"); 36 37 builder.InsertCell(); 38 builder.CellFormat.Width = width2; 39 builder.Write("证件类型"); 40 41 builder.InsertCell(); 42 builder.CellFormat.Width = width3; 43 builder.Write("证件号码"); 44 45 builder.InsertCell(); 46 builder.CellFormat.Width = width4; 47 builder.Write("联系方式"); 48 49 // 每一行结束一定要EndRow() 不然每一行的样式会受到影响 50 builder.EndRow(); 51 52 // 输出4行空表格 53 for (var i = 0; i < 4; i++) 54 { 55 builder.InsertCell(); 56 builder.CellFormat.Width = width1; 57 58 builder.InsertCell(); 59 builder.CellFormat.Width = width2; 60 61 builder.InsertCell(); 62 builder.CellFormat.Width = width3; 63 64 builder.InsertCell(); 65 builder.CellFormat.Width = width4; 66 67 builder.EndRow(); 68 } 69 70 var fileName = "WaterMark(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 71 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 72 }
效果如下:
其实还有很多的东西需要演示,比如程序输出页眉、页尾等。但是篇幅实在是太大了,而且接下来还有内容。还是那句话,更多内容查看帮助文档,我在这里就是引导
大家怎么做,上面那几个实例掌握后,几乎就差不多了。下面是结合上面的实例进行演示。因为实际的业务需求并没有那么单一。
书签很有用,可以让我们在程序中通过提前设置好的书签快速定位到要输出的位置。
下面是一个word文档,先设置好书签(直接在word文档上设置,前面已经说过说过如何设置输钱了书签),书签名为"UserInfoTable",具体如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 protected void OutPutTableWidthBookMark_Click(object sender, EventArgs e) 2 { 3 var path = Server.MapPath("../Document/Aspose.WordBookMark.doc"); 4 Document doc = new Document(path); 5 DocumentBuilder builder = new DocumentBuilder(doc); 6 7 Aspose.Words.Font font = builder.Font; 8 font.Bold = false; 9 font.Size = 12; 10 11 // 设置表格的样式 12 builder.RowFormat.Borders.LineStyle = LineStyle.Single; 13 builder.RowFormat.HeightRule = HeightRule.Exactly; 14 builder.RowFormat.Alignment = RowAlignment.Center; 15 // 设置行高 16 builder.RowFormat.Height = 24; // 设置单元格的高度 17 18 // 设置每个单元格内的样式 19 builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; 20 builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; 21 builder.CellFormat.VerticalMerge = CellMerge.First; 22 builder.CellFormat.HorizontalMerge = CellMerge.None; 23 24 // 定义一个存储模板表头每个单元格宽度的集合 25 List<double> cellWidths = new List<double>(); 26 // 根据集合列数 27 for (int i = 0; i < 4; i++) 28 { 29 // 参数依次是: "表格的索引"、"行的索引"、"列的索引"、"单元格内部索引" 30 builder.MoveToCell(0, 0, i, 0); //移动单元格 (代表着表头的cell依次移动) 31 double width = builder.CellFormat.Width;//获取单元格宽度 32 cellWidths.Add(width); 33 } 34 35 // 直接定位到书签的位置 (根据书签名定位的) 36 builder.MoveToBookmark("UserInfoTable"); 37 // 输出表格 38 for (var i = 0; i < 6; i++) 39 { 40 builder.InsertCell(); 41 // 设置单元格宽度 42 builder.CellFormat.Width = cellWidths[0]; 43 builder.Write("张三"+i); 44 45 builder.InsertCell(); 46 builder.CellFormat.Width = cellWidths[1]; 47 builder.Write("身份证" + i); 48 49 builder.InsertCell(); 50 builder.CellFormat.Width = cellWidths[2]; 51 builder.Write("ABC" + i); 52 53 builder.InsertCell(); 54 builder.CellFormat.Width = cellWidths[3]; 55 builder.Write("888" + i); 56 57 builder.EndRow(); 58 } 59 // 结束表格 60 builder.EndTable(); 61 // 结束书签 62 builder.EndBookmark("UserInfoTable"); 63 64 var fileName = "OutPutTableWidthBookMark(" + DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss") + ").doc"; 65 doc.Save(fileName, SaveFormat.Doc, SaveType.OpenInBrowser, Response); 66 }
效果如下:
总结
Aspose.Word 几乎可以解决我们各种复杂word文档的输出问题,以上的内容只是它的冰山一角,如果上面概括的内容满足不了你的需求,那么就看看帮助文档吧,或者联系我。
这部分代码你也可以通过开篇去下载。觉得有帮助就点击右下角"推荐"一个。