公共類
標題樣式
字體大小 margin設置 標題 h1-h6
namespace Common.Bo
{public class TitleStyle{/// <summary>/// 標題樣式/// </summary>/// <param name="tag"></param>/// <param name="fontSize"></param>/// <param name="margin"></param>public TitleStyle(float fontSize, string margin){FontSize = fontSize;Margin = margin;}/// <summary>/// 標題樣式/// </summary>/// <param name="tag"></param>/// <param name="fontSize"></param>/// <param name="margin"></param>public TitleStyle(string tag, float fontSize, string margin){Tag = tag;FontSize = fontSize;Margin = margin;}public string Tag { get; set; } = "h1";public float FontSize { get; set; }public string Margin { get; set; }//"h1","35px","margin-top:0px;"}
}
word的目錄信息
namespace Common.Bo
{/// <summary>/// word目錄信息/// </summary>public class WordMenuInfo{public string Title { get; set; }public int PageNumber { get; set; }}
}
公共屬性
標題級別 對應的標題樣式 漢字與數字標題對應關系
using Aspose.Words;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Text.RegularExpressions;namespace Common.Bo
{public class CommonStyle{#region 標題級別 如一級標題 三級標題protected const int oneTitileLevel = 1;protected const int twoTitileLevel = 2;protected const int threeTitileLevel = 3;protected const int fourTitileLevel = 4;protected const int fiveTitileLevel = 5;#endregion#region 只讀的標題樣式public static ReadOnlyDictionary<int, TitleStyle> titleDict = new ReadOnlyDictionary<int, TitleStyle>(new Dictionary<int, TitleStyle>{{ 0,new TitleStyle("h1",35,"margin-top:0px;")},{ 1,new TitleStyle("h1",35,"margin-top:0px;")},{ 2,new TitleStyle("h2",33,"margin-top:0px;")},{ 3,new TitleStyle("h3",32,"margin-top:0px;")},{ 4,new TitleStyle("h4",30,"margin-top:0px;")},{ 5,new TitleStyle("h5",28,"margin-top:0px;")},});#endregion#region 文件格式protected static ReadOnlyDictionary<string, string> imageFormatterDict = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>{{ ".jpg",default},{ ".jpeg",default},{ ".png",default},{ ".emf",default},{ ".wmf",default},{ ".bmp",default},});protected static ReadOnlyDictionary<string, string> wordFormatterDict = new ReadOnlyDictionary<string, string>(new Dictionary<string, string>{{ ".doc",default},{ ".docx",default}});#endregion#region 數字與大小漢字對照標 最大可是999=》九百九十九protected static Dictionary<int, string> numberUpCaseDict = new Dictionary<int, string>(){{0,"零"},{1,"一"},{2,"二"},{3,"三"},{4,"四"},{5,"五"},{6,"六"},{7,"七"},{8,"八"},{9,"九"},{10,"十"}};#endregion#region 1-5級 標題格式規則校驗與標題級別protected static ReadOnlyDictionary<Regex, int> titleRegexRule= new ReadOnlyDictionary<Regex, int>(new Dictionary<Regex, int>{{new Regex("^\\d{1,3}[\\.、]([^0-9]|s)"),1},{new Regex("^\\d{1,3}[\\.、]\\d{1,3}[\\.、]?([^0-9]|s)"),2},{new Regex("^\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]?([^0-9]|s)"),3},{new Regex("^\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]?([^0-9]|s)"),4},{new Regex("^\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]\\d{1,3}[\\.、]?([^0-9]|s)"),5}});#endregionstatic CommonStyle(){int curV;StringBuilder sbf;for (int i = 11; i < 900; i++){sbf = new StringBuilder();if ((curV = i / 100) > 0){sbf.Append(numberUpCaseDict[curV] + "百");}if ((curV = i % 100 / 10) > 0){sbf.Append(i > 10 && i < 20 ? "十" : numberUpCaseDict[curV] + "十");}else if (i > 100 && curV > 0){sbf.Append("零");}if ((curV = i % 10) > 0){sbf.Append(numberUpCaseDict[curV]);}numberUpCaseDict.Add(i, sbf.ToString());}}}
}
核心代碼
生成word里面相關部分 如標題 文本 表格 圖片 目錄
using Aspose.Pdf.Operators;
using Aspose.Words;
using Aspose.Words.Drawing;
using Aspose.Words.Tables;
using Common.Bo;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;namespace Common.Util
{/// <summary>/// Aspose.Words /// 生成table /// 生成標題/// 生成文本 /// 插入圖片/// 生成目錄/// 獲取目錄/// 合并word/// 轉化pdf /// /// </summary>public class AsposeWordUtil : CommonStyle{/// <summary>/// 創建word document/// </summary>/// <param name="comPath"></param>/// <param name="comDoc"></param>/// <param name="comBuilder"></param>public static void CreateWordDocument(string comPath, out Document comDoc, out DocumentBuilder comBuilder){comDoc = new Document(comPath);comBuilder = new DocumentBuilder(comDoc);comBuilder.PageSetup.PaperSize = PaperSize.A4;//頁面設置為A4}/// <summary>/// 創建表格/// </summary>/// <typeparam name="T"></typeparam>/// <param name="curBuilder"></param>/// <param name="bookName"></param>/// <param name="list"></param>/// <param name="columNames"></param>/// <param name="propNames"></param>/// <param name="customFunc"></param>/// <param name="serialNum"></param>/// <param name="titleRemark"></param>public static void CreateTable<T>(DocumentBuilder curBuilder, string bookName, IList<T> list,string[] columNames, string[] propNames, Action<DocumentBuilder> customFunc = null, bool serialNum = false, string titleRemark = null){Type tbc = typeof(T);Dictionary<string, Func<T, string>> titleColumsDict = new Dictionary<string, Func<T, string>>();for (int i = 0; i < columNames.Length; i++){System.Reflection.PropertyInfo propertyInfo = tbc.GetProperty(propNames[i]);titleColumsDict[columNames[i]] = ob => propertyInfo.GetValue(ob, null)?.ToString();}CreateTable(curBuilder, bookName, list, titleColumsDict, customFunc, serialNum, titleRemark);}/// <summary>/// 創建表格/// </summary>/// <typeparam name="T"></typeparam>/// <param name="curBuilder"></param>/// <param name="bookName">word模板標簽名稱</param>/// <param name="list"></param>/// <param name="titleColumsDict">表格列名與取值的Func</param>/// <param name="customFunc">自定義函數處理 比如生成合計列</param>/// <param name="serialNum">是否需要序號</param>/// <param name="titleRemark">在表格之上需要生成文本信息</param>public static void CreateTable<T>(DocumentBuilder curBuilder, string bookName, IList<T> list, Dictionary<string, Func<T, string>> titleColumsDict, Action<DocumentBuilder> customFunc = null, bool serialNum = false, string titleRemark = null){//移到標簽部分if (bookName != null){curBuilder.MoveToBookmark(bookName);}//表格不存在if (!list.Any()){return;}string[] columNames = titleColumsDict.Select(p => p.Key).ToArray();//默認填寫表頭內容if (!string.IsNullOrWhiteSpace(titleRemark)){curBuilder.StartTable();curBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Left; // RowAlignment.Center; curBuilder.RowFormat.Height = 20;curBuilder.InsertCell();curBuilder.CellFormat.Width = 500 * (serialNum ? 1 : 0 + columNames.Length);curBuilder.CellFormat.VerticalAlignment = CellVerticalAlignment.Top;curBuilder.CellFormat.Borders[0].LineStyle = LineStyle.Single;curBuilder.CellFormat.Borders[1].LineStyle = LineStyle.None;curBuilder.CellFormat.Borders[2].LineStyle = LineStyle.None;curBuilder.CellFormat.Borders[3].LineStyle = LineStyle.None;//字體大小 curBuilder.Font.Size = 9.5d;//是否加粗 curBuilder.Bold = false;curBuilder.Write(titleRemark);curBuilder.EndRow();curBuilder.EndTable();}Type tbc = typeof(T);Table table = curBuilder.StartTable();curBuilder.ParagraphFormat.Alignment = ParagraphAlignment.Center; // RowAlignment.Center; curBuilder.RowFormat.Height = 20;//操作序號列if (serialNum){curBuilder.InsertCell();//使用固定的列寬//table.AutoFit(AutoFitBehavior.AutoFitToContents);//Table單元格邊框線樣式 curBuilder.CellFormat.Borders.LineStyle = LineStyle.Single;//Table此單元格寬度 curBuilder.CellFormat.Width = 500;curBuilder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;//字體大小 curBuilder.Font.Size = 10;//是否加粗 curBuilder.Bold = true;curBuilder.Write("序號");}//添加列頭 for (int i = 0; i < columNames.Length; i++){curBuilder.InsertCell();//使用固定的列寬//table.AutoFit(AutoFitBehavior.AutoFitToContents);//Table單元格邊框線樣式 curBuilder.CellFormat.Borders.LineStyle = LineStyle.Single;//Table此單元格寬度 curBuilder.CellFormat.Width = 500;curBuilder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;//字體大小 curBuilder.Font.Size = 10;//是否加粗 curBuilder.Bold = true;//向此單元格中添加內容 //builder.Write(dt.Columns[i].ColumnName);curBuilder.Write(columNames[i]);}curBuilder.EndRow();//結束表頭行 下次InsertCell開啟新的行//添加每行數據 for (int i = 0; i < list.Count; i++){curBuilder.RowFormat.HeightRule = HeightRule.Auto;//操作序號列if (serialNum){//插入Table單元格 curBuilder.InsertCell();//Table單元格邊框線樣式 curBuilder.CellFormat.Borders.LineStyle = LineStyle.Single;//字體大小 curBuilder.Font.Size = 10;//是否加粗 curBuilder.Bold = false;//向此單元格中添加內容 curBuilder.Write((i + 1).ToString());}foreach (var tcItem in titleColumsDict){//插入Table單元格 curBuilder.InsertCell();//Table單元格邊框線樣式 curBuilder.CellFormat.Borders.LineStyle = LineStyle.Single;//字體大小 curBuilder.Font.Size = 10;//是否加粗 curBuilder.Bold = false;//向此單元格中添加內容 curBuilder.Write(tcItem.Value.Invoke(list[i]) ?? "");}//Table行結束 curBuilder.EndRow();}if (customFunc != null){customFunc(curBuilder);}curBuilder.EndTable();}/// <summary>/// 設置書簽具體的值/// </summary>/// <param name="v"></param>/// <param name="projectName"></param>public static void SetBookVal(Document doc, string bookName, string value){if (!string.IsNullOrEmpty(value)){doc.Range.Bookmarks[bookName].Text = value;}}/// <summary>/// 當前的domBuiler操作 插入圖片 ==》追加pdf內容/// </summary>/// <param name="curBuilder"></param>/// <param name="filePath"></param>public static void AppendImageAndPdf(DocumentBuilder curBuilder, string filePath){//文件資源不存在 ==》不插入圖片if (!File.Exists(filePath)){return;}//如果是文件夾if (Directory.Exists(filePath)){FileInfo[] fileInfoArray = new DirectoryInfo(filePath).GetFiles();#region 處理圖片FileInfo[] fileInfos = fileInfoArray.Where(fi => imageFormatterDict.ContainsKey(fi.Extension.ToLower())).OrderBy(f => f.Name).ToArray();foreach (FileInfo item in fileInfos){AppendImageAndPdf(curBuilder, item.FullName);//將圖片文件追加進去}#endregion}else{using (Image image = Image.FromFile(filePath)){curBuilder.InsertBreak(BreakType.SectionBreakNewPage);int imgWidth2 = image.Width;int imgHeight2 = image.Height;//適配寬高AdaptWh(curBuilder, ref imgWidth2, ref imgHeight2);curBuilder.InsertImage(image, RelativeHorizontalPosition.Page, 10.0, RelativeVerticalPosition.Page, 5.0, imgWidth2, imgHeight2, WrapType.None);}}}/// <summary>/// 插入標題或文本/// </summary>/// <param name="comBuilder"></param>/// <param name="title"></param>/// <param name="titleLevel"></param>/// <param name="newPage">插入新的一頁 一般為true是防止圖片把文字覆蓋了</param>/// <param name="marginCss">額外的樣式</param>/// <param name="isTitle">是否是1-5級標題 如果不是則用div</param>public static void InsertDefinedTitle(DocumentBuilder comBuilder, string title, int titleLevel, bool newPage = false,string marginCss = null, bool isTitle = true){//防止被圖片覆蓋if (newPage){comBuilder.InsertBreak(BreakType.SectionBreakNewPage);}TitleStyle curValue = null;curValue = titleDict.TryGetValue(titleLevel, out curValue) ? curValue : new TitleStyle("h1", 35, "margin-top:0px;");marginCss = marginCss ?? (curValue.Margin ?? "margin-top:0px;");if (newPage){marginCss = "margin-top:300px;";}string hmark = isTitle ? curValue.Tag : "div";string fontSize = curValue.FontSize + "px";comBuilder.InsertHtml($"<{hmark} style='text-align:center;font-family:宋體;font-size:{fontSize};{marginCss}'>" + title + $"</{hmark}><br/>");}/// <summary>/// 插入圖片/// </summary>/// <param name="curBuilder"></param>/// <param name="filePath"></param>/// <param name="imgWidth"></param>/// <param name="imgHeight"></param>public static void InsertImage(DocumentBuilder curBuilder, string filePath, int? imgWidth = null, int? imgHeight = null, WrapType wrapType = WrapType.None){using (Image image = Image.FromFile(filePath)){int _imgWidth = imgWidth ?? image.Width;int _imgHeight = imgHeight ?? image.Height;//適配寬高if (imgWidth != null && imgHeight != null){AdaptWh(curBuilder, ref _imgWidth, ref _imgHeight);}curBuilder.InsertImage(image, RelativeHorizontalPosition.Page, 10, RelativeVerticalPosition.Page, 5, _imgWidth, _imgHeight, wrapType);}}/// <summary>/// 圖片適配(頁面寬高)/// </summary>/// <param name="imgWidth"></param>/// <param name="imgHeight"></param>public static void AdaptWh(DocumentBuilder curBuilder, ref int imgWidth, ref int imgHeight){int maxWidth = (int)(curBuilder.PageSetup.PageWidth * 0.92);int maxHeight = (int)(curBuilder.PageSetup.PageHeight * 0.92);//長寬比視頻if (imgWidth > maxWidth){imgHeight = Convert.ToInt32(decimal.Multiply(decimal.Divide(maxWidth, (int)imgWidth), (int)imgHeight));imgWidth = maxWidth;}if (imgHeight > maxHeight){imgWidth = Convert.ToInt32(decimal.Multiply(decimal.Divide(maxHeight, (int)imgHeight), (int)imgWidth));imgHeight = maxHeight;}}/// <summary>/// 內容歸檔并書寫頁面/// </summary>/// <param name="doc">主doc</param>/// <param name="mergeDoc">被合并的doc</param>/// <param name="titleList">標題信息</param>/// <param name="indexTitle"></param>public static void PlaceOnFile(Document doc, Document mergeDoc){doc.AppendDocument(mergeDoc, ImportFormatMode.KeepSourceFormatting);}/// <summary>/// 獲取目錄信息/// </summary>/// <param name="doc"></param>public static List<WordMenuInfo> GetDocMenuInfo(Document doc){#region 獲取目錄信息List<WordMenuInfo> pageInfoList = new List<WordMenuInfo>();foreach (Aspose.Words.Fields.Field field in doc.Range.Fields){if (field.Type.Equals(Aspose.Words.Fields.FieldType.FieldHyperlink)){string value;string[] vs;if (!string.IsNullOrWhiteSpace(field.Result)){//頁碼內容 此次使用正則獲取 標題信息(含頁碼)value = Regex.Replace(field.Result, @"\s{1,20} PAGEREF _Toc\d+\s+\\h", "").Replace("\u0015", "").Replace("\u0014", "");value = Regex.Replace(value, @"\s{1,2}[^\d]{1,12}$", "###");vs = Regex.Split(value, @"\d{1,12}$");pageInfoList.Add(new WordMenuInfo { Title = vs[0], PageNumber = Convert.ToInt32(value.Replace(vs[0], "").Trim()) });}}}return pageInfoList;#endregion}/// <summary>/// 生成目錄/// </summary>public void CreateToc(DocumentBuilder builder, string bookMark = "目錄位置"){bool moveSuccess = builder.MoveToBookmark(bookMark);if (moveSuccess){//目錄居左builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;//插入目錄,這是固定的builder.InsertTableOfContents("\\o \"1-3\" \\h \\z \\u");builder.Document.UpdateFields();// 更新域//builder.Document.UpdatePageLayout();}}}
}