公共类
标题样式
字体大小 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();}}}
}