本文簡單的介紹一下通過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("測試標題");
以上內容希望對大家開發過程也有幫助!