C# Aspose.Words for .NET操作Word生成自定义word方案
本文简单的介绍一下通过c#语言生成自定义word!
首先我们需要引用一个dll文件 Aspose.Words.dll
这里我已经下载一个比较适用的Aspose.Words.dll 文件了,链接: https://pan.baidu.com/s/1GkxfW0E24a0N-7YPlTdyrQ 提取码: vd3a
效果展示:
我这里是通过提前预定好章节,以及章节的顺序章节的名称在前台去处理好,同时上传了需要引用的word,可以引用上传文件中的的图片、段落、表格等等
最后通过配置每个章节需要展示的内容以此生成整体的word方案!
下面展示一些主要的方法:
方案的生成和保存=》
string CreatePath = System.Web.HttpContext.Current.Server.MapPath("../FixedDocument/方案模板.doc"); Document doc = new Document(CreatePath); DocumentBuilder builder = new DocumentBuilder(doc); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.Font.Name = "宋体"; builder.Font.Bold = true; builder.Font.Size = 14; builder.ParagraphFormat.Alignment = ParagraphAlignment.Left; builder.Writeln("测试内容"); string FileName = "测试方案"+ System.DateTime.Now.ToString("HHmmssffff") + ".doc"; string MainPath = System.Web.HttpContext.Current.Server.MapPath("../UploadFile/" + FileName); doc.Save(MainPath );
设置标题=》
//======================================== Dictionary<String, String> Dic = new Dictionary<String, String> { {"1","一、"},{"2","二、"},{"3","三、"},{"4","四、"},{"5","五、"},{"6","六、"},{"7","七、"},{"8","八、"},{"9","九、"},{"10","十、"},{"11","十一、"}, {"12","十二、"},{"13","十三、"},{"14","十四、"},{"15","十五、"},{"16","十六、"},{"17","十七、"},{"18","十八、"},{"19","十九、"},{"20","二十、"}, {"0.1",".1"},{"0.2",".2"},{"0.3",".3"},{"0.4",".4"},{"0.5",".5"},{"0.6",".6"},{"0.7",".7"},{"0.8",".8"},{"0.9",".9"},{"0.01",".1"},{"0.02",".2"}, {"0.03",".3"},{"0.04",".4"},{"0.05",".5"},{"0.06",".6"},{"0.07",".7"},{"0.08",".8"},{"0.09",".9"} }; double first = 0;//一级标题索引 double second = 0.0;//二级标题索引 double third = 0.00;//三级标题索引 //======================================== //生成标题规则 switch (model.level) //这里的model.level是章节的级别 { case "一级": first = first + 1; second = 0.0; third = 0.00; tempdic = first.ToString(); tempstr = ""; break; case "二级": second = second + 0.1; third = 0.00; tempdic = second.ToString(); tempstr = first.ToString(); break; case "三级": third = third + 0.01; tempdic = third.ToString(); tempstr = (first + second).ToString(); break; } string title = tempstr + Dic[tempdic] + model.template;//生成的标题 //插入标题 InsertH(builder, title, model.level); //======================================== public void InsertH(DocumentBuilder builder, string Text, string TileType) { switch (TileType) { case "一级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading1; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; imgindex = 1;//用于章节内插入图片的标题排序 例如: 表1-1 xxxx 到章节二变成 表2-1 xxxx tableindex = 1;//用于章节内插入表格的标题排序 break; case "二级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Heading2; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "三级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 24; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "四级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "五级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "六级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "七级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; case "八级": builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.BodyText; builder.ParagraphFormat.Style.Font.Bold = true; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Bold = true; builder.Writeln(Text); builder.ParagraphFormat.StyleIdentifier = StyleIdentifier.Normal; builder.Font.Bold = false; break; default: //默认 break; } }
以上标题的生成规则看项目需求的需要,我这里一级标题中文数字,二级标题和三级标题阿拉伯数据,这里有个问题是标题只能到十位以下,标题级别也只有三级(一级、二级、三级)
添加段落=》
//添加段落 public void InsertText(DocumentBuilder builder, string Text) { ParagraphFormat paragraphFormat = builder.ParagraphFormat; paragraphFormat.FirstLineIndent = 24;//首行缩进 paragraphFormat.Alignment = ParagraphAlignment.Justify; paragraphFormat.KeepTogether = true; paragraphFormat.Style.Font.Size = 12; paragraphFormat.Style.Font.Name = "宋体"; builder.Write(Text); paragraphFormat.FirstLineIndent = 0; }
添加图片
//添加图片 public void InsertImage(DocumentBuilder builder, string imgUrl) { builder.InsertImage(imgUrl); if (File.Exists(imgUrl)) { //第一种方式 builder.InsertImage(imgUrl); //第二种方式 //Image image = Image.FromFile(imgUrl); //builder.InsertImage(image); } }
添加表格(直接从数据库DataTable数据插入生成表格) -----格式未调整
public void InsertTable(DocumentBuilder builder, string sql) { Bll_WordTemplateSelection bll = new Bll_WordTemplateSelection(); List<string> listCol = new List<string>(); List<string> listText = new List<string>(); DataTable dt = bll.GetTextBySQL(sql); string str = string.Empty; foreach (DataColumn col in dt.Columns) { listCol.Add(col.ColumnName);//获取到DataColumn列对象的列名 } //文档中插入表格 Table table = builder.StartTable(); builder.RowFormat.Borders.Color = Color.Black; //插入表头 InsertHeaderCell(builder, listCol); foreach (DataRow row in dt.Rows) { listText = new List<string>(); foreach (string ss in listCol) { listText.Add(row[ss].ToString()); } InsertCell(builder, listText); } builder.EndTable(); //自动使表格适合单元格内容 //table.AutoFit(AutoFitBehavior.AutoFitToContents); } public void InsertHeaderCell(DocumentBuilder builder, List<string> ArrText) { builder.Font.Size = 8; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Name = "宋体"; builder.Font.Bold = true; builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; for (int i = 0; i < ArrText.Count; i++) { builder.InsertCell(); builder.CellFormat.Width = 100; builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; //builder.CellFormat.Shading.BackgroundPatternColor = Color.White; //builder.CellFormat.Shading.BackgroundPatternColor = Color.FromArgb(198, 217, 241); builder.Write(ArrText[i]); } builder.EndRow(); } public void InsertCell(DocumentBuilder builder, List<string> ArrText) { builder.ParagraphFormat.Alignment = ParagraphAlignment.Left; builder.Font.Size = 8; builder.ParagraphFormat.FirstLineIndent = 0; builder.Font.Name = "宋体"; builder.Font.Bold = false; for (int i = 0; i < ArrText.Count; i++) { builder.InsertCell(); builder.CellFormat.Width = 100; builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center; //builder.CellFormat.Shading.BackgroundPatternColor = Color.White; builder.Write(ArrText[i]); } builder.EndRow(); }
插入页眉页脚=》
//根据插入页眉 public void InsertHeader(DocumentBuilder builder, string Text) { Section currentSection = builder.CurrentSection; PageSetup pageSetup = currentSection.PageSetup; pageSetup.DifferentFirstPageHeaderFooter = true; // --- Create header for the first page. --- pageSetup.HeaderDistance = 20; builder.MoveToHeaderFooter(HeaderFooterType.HeaderFirst); builder.ParagraphFormat.Alignment = ParagraphAlignment.Center; // Set font properties for header text. builder.Font.Name = "宋体"; builder.Font.Bold = true; builder.Font.Size = 12; pageSetup.HeaderDistance = 20; builder.Write(Text); builder.MoveToHeaderFooter(HeaderFooterType.HeaderPrimary); // --- Create footer for pages other than first. --- //builder.MoveToHeaderFooter(HeaderFooterType.FooterPrimary); builder.StartTable(); // Clear table borders. builder.CellFormat.ClearFormatting(); builder.InsertCell(); // Set the second cell to 2/3 of the page width. builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 * 3 / 4); builder.Write(Text); // Align this text to the right. builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Center; builder.InsertCell(); // Set first cell to 1/3 of the page width. builder.CellFormat.PreferredWidth = PreferredWidth.FromPercent(100 / 4); builder.Write("第 "); builder.InsertField("PAGE", ""); builder.Write(" 页/共 "); builder.InsertField("NUMPAGES", ""); builder.Write(" 页"); // Align this text to the left. builder.CurrentParagraph.ParagraphFormat.Alignment = ParagraphAlignment.Center; builder.RowFormat.Borders.Color = Color.White; builder.EndRow(); builder.EndTable(); builder.MoveToDocumentEnd(); }
根据关键字查找出word中的段落=》
/// <summary>
/// 获取关键字选中的段落
/// </summary>
/// <param name="CHAPTER_KEY_START">开始章节的标题</param>
/// <param name="CHAPTER_KEY_END">结束章节的标题</param>
/// <param name="PARAGRAPH_KEY">开始章节与结束章节段落的第一段话关键字,多个关键字用 # 隔开</param>
/// <param name="WordPath">word的路径</param>
/// <returns>返回查找出段落的所有集合</returns>
public List<string> GetDocumentText(string CHAPTER_KEY_START, string CHAPTER_KEY_END, string PARAGRAPH_KEY,string WordPath) { List<string> list = new List<string>(); List<string> Childlist = new List<string>(); string dataDir = WordPaht;//word文档的路径 Document doc = new Document(dataDir); //更新一下目录 doc.UpdateFields(); ParagraphCollection coll = doc.FirstSection.Body.Paragraphs; if (!string.IsNullOrEmpty(CHAPTER_KEY_START) && !string.IsNullOrEmpty(CHAPTER_KEY_END)) { bool flag = false; foreach (Paragraph par in coll) { if (par.Range.Text.Trim() != "" && !par.Range.Text.Trim().Contains("_Toc"))//去除标题 { if (par.Range.Text.Trim().Contains(CHAPTER_KEY_END)) { flag = false; break; } } if (par.Range.Text.Trim() != "" && !par.Range.Text.Trim().Contains("_Toc"))//去除标题 { if (flag) { if (par.ParagraphFormat.Alignment != ParagraphAlignment.Center)//去除图片描述及表格的文字描述 { list.Add(par.Range.Text); } } if (par.Range.Text.Trim().Contains(CHAPTER_KEY_START)) { flag = true; } } } //晒选章节中被关键字选中的段落,如果没有关键字则取章节中所有段落 if (!string.IsNullOrEmpty(PARAGRAPH_KEY)) { string[] Arr = PARAGRAPH_KEY.Split('#'); foreach (string tempText in Arr) { foreach (string text in list) { if (text.Contains(tempText)) { Childlist.Add(text); } } } } else { Childlist = list; } } return Childlist; }
根据关键字查找出word中的表格=》
//根据关键字查找表(TABLE_KEY 为表格单元格的关键字,多个单元格的关键字用#隔开) public void SearchTable(string TABLE_KEY,string WordName) { string[] KeyArr = TABLE_KEY.Split('#');//拆分关键字 if (KeyArr.Length>=1) { //查找表 string dataDir = System.Web.HttpContext.Current.Server.MapPath("../QuoteWord/" + WordName); Document doc = new Document(dataDir); //doc.UpdateFields(); string dataDir1 = System.Web.HttpContext.Current.Server.MapPath("../Template/"); Document doc1 = new Document(); //获取所有的table NodeCollection allTables = doc.GetChildNodes(NodeType.Table, true); foreach (Table ta in allTables) { int index = 0; foreach (string ss in KeyArr) { foreach (Row row in ta.Rows) { for (int i = 0; i < row.Cells.Count; i++) { string str = row.Cells[i].Range.Text.Replace("\a", "").Replace("\r", "").Replace("S", "").Trim(); str = str.Replace(" ", ""); if (str.Contains(ss)) { index++; } } } } if (index == KeyArr.Length) { Table tb=null; if (TABLE_KEY == "位置#靶点深度") //我这里查找的表格需要做删除行和列操作 { tb = DeleteTableRow(ta,0);//删除第一行 tb = DeleteTableRow(tb, 0);//再删除是已经删除第一行后的表格的第一行 tb = DeleteTableRow(tb, 0);//继续操作上一步操作 tb = DeleteTableColumn(tb,0);//删除第一列 } else { tb = ta; } ArrayList list1 = new ArrayList(); list1.Add(tb); doc1 = GenerateDocument(doc, list1); if (!string.IsNullOrEmpty(TABLE_KEY)) { dataDir1 = dataDir1 + TABLE_KEY + ".docx"; doc1.Save(dataDir1); } break; } } } }
赋值表格=》
//复制表格 public static Document GenerateDocument(Document srcDoc, ArrayList nodes) { // Create a blank document. Document dstDoc = new Document(); // Remove the first paragraph from the empty document. dstDoc.FirstSection.Body.RemoveAllChildren(); // Import each node from the list into the new document. Keep the original formatting of the node. NodeImporter importer = new NodeImporter(srcDoc, dstDoc, ImportFormatMode.KeepSourceFormatting); foreach (Node node in nodes) { Node importNode = importer.ImportNode(node, true); dstDoc.FirstSection.Body.AppendChild(importNode); } // Return the generated document. return dstDoc; }
删除表格的行和列=》
//删除表格行 public Table DeleteTableRow(Table table ,int index) { Table NewTable = table; try { //删除行第二种方法 NewTable.Rows.RemoveAt(index); }catch(Exception ex) { return table;//找不到对应索引直接返回原表 } return NewTable; } //删除表格列 public Table DeleteTableColumn(Table table, int index) { Table NewTable = table; try { //从表中获取第1列 Column column = Column.FromIndex(NewTable, 0); //删除列 column.Remove(); } catch (Exception ex) { return table; } return NewTable; }
插入标签(同时调用两个方法,前后顺序不能反,标签内容需要一致)=》
//插入书签 builder.StartBookmark("标签字符串"); builder.EndBookmark("标签字符串");
根据标签位置插入另一个word的全部内容=》
var localPath = System.Web.HttpContext.Current.Server.MapPath("../UploadFile/" + DocumentName + System.DateTime.Now.ToString("HHmmssffff") + ".doc"); Document docMain = new Document(localPath); string NewTablePath = OnlineWordPath + "ResourceManagement/FixedDocument/" + book; //这里的book是word文档的名称,同时也是标签的内容(两者为了方表示用设置了相同的值) Document tabdoc = new Document(NewTablePath); //定位到书签:insertionPlace Bookmark bookmark = docMain.Range.Bookmarks[book]; //将subDoc中的内容插入到mainDoc中的书签book位置 InsertDocument(bookmark.BookmarkStart.ParentNode, tabdoc); string FileName = "测试方案"+ System.DateTime.Now.ToString("HHmmssffff") + ".doc"; string MainPath = System.Web.HttpContext.Current.Server.MapPath("../UploadFile/" + FileName); docMain.Save(MainPath); /// <summary> /// 在指定节点之后插入外部文档的内容。 /// 插入文档的分节符和节格式将被忽略。 /// </summary> static void InsertDocument(Node insertAfterNode, Document srcDoc) { // Make sure that the node is either a paragraph or table. if ((!insertAfterNode.NodeType.Equals(NodeType.Paragraph)) & (!insertAfterNode.NodeType.Equals(NodeType.Table))) throw new ArgumentException("The destination node should be either a paragraph or table."); // We will be inserting into the parent of the destination paragraph. CompositeNode dstStory = insertAfterNode.ParentNode; // This object will be translating styles and lists during the import. NodeImporter importer = new NodeImporter(srcDoc, insertAfterNode.Document, ImportFormatMode.KeepSourceFormatting); // Loop through all sections in the source document. foreach (Section srcSection in srcDoc.Sections) { // Loop through all block level nodes (paragraphs and tables) in the body of the section. foreach (Node srcNode in srcSection.Body) { // Let's skip the node if it is a last empty paragraph in a section. if (srcNode.NodeType.Equals(NodeType.Paragraph)) { Paragraph para = (Paragraph)srcNode; if (para.IsEndOfSection && !para.HasChildNodes) continue; } // This creates a clone of the node, suitable for insertion into the destination document. Node newNode = importer.ImportNode(srcNode, true); // Insert new node after the reference node. dstStory.InsertAfter(newNode, insertAfterNode); insertAfterNode = newNode; } } }
替换word中的内容=》
//localPath为word路径 Document docMain = new Document(localPath); //将word中全部的“你” 替换为 “我” docMain.Range.Replace("你", "我", new FindReplaceOptions(FindReplaceDirection.Forward));
使用目录=》
Document doc = new Document(); DocumentBuilder builder = new DocumentBuilder(doc); //插入目录(开始word封面后一页插入) builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u"); //word内容插入后更新目录 //更新目录 doc.UpdateFields(); string SavePath=System.Web.HttpContext.Current.Server.MapPath("../Template/")+System.DateTime.Now.ToString("HHmmssffff") + ".doc"; doc.Save(SavePath);
插入附件=》
Document doc = new Document(); //AffixUrl为附件word的路径 AppendDoc(doc, AffixUrl);
整体的主要方法差不多就这些,代码后续会继续优化!这里word的样式没有介绍,我们可以直接用代码控制,也可以沿用已有的word的格式!
例子:https://blog.csdn.net/weixin_42727550/article/details/108257722?utm_medium=distribute.pc_relevant_bbs_down.none-task--2~all~sobaiduend~default-3.nonecase&depth_1-utm_source=distribute.pc_relevant_bbs_down.none-task--2~all~sobaiduend~default-3.nonecase
StyleCollection styles; string CreatePath = System.Web.HttpContext.Current.Server.MapPath("../FixedDocument/方案模板.doc"); Document doc = new Document(CreatePath); DocumentBuilder builder = new DocumentBuilder(doc); styles = doc.Styles; //标题插入 builder.ParagraphFormat.Style = styles["Title1"]; builder.Writeln("测试标题");
以上内容希望对大家开发过程也有帮助!