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