分享一个用C#写的Aspose.Words生成word的工具类

公共类

标题样式

字体大小 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();
			}
		}
	}
}


最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-09 23:28:02       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-09 23:28:02       106 阅读
  3. 在Django里面运行非项目文件

    2023-12-09 23:28:02       87 阅读
  4. Python语言-面向对象

    2023-12-09 23:28:02       96 阅读

热门阅读

  1. c语言编程题经典100例——(90~95例)

    2023-12-09 23:28:02       52 阅读
  2. [动态规划]最长公共子序列

    2023-12-09 23:28:02       51 阅读
  3. 从Android源码中生成系统签名文件

    2023-12-09 23:28:02       55 阅读
  4. 面向无组织点云中快速鲁棒的边缘提取方法

    2023-12-09 23:28:02       53 阅读
  5. 考研真题数据结构

    2023-12-09 23:28:02       53 阅读
  6. Centos7安装docker支持NVIDIA GPU

    2023-12-09 23:28:02       49 阅读
  7. 反向传播算法

    2023-12-09 23:28:02       52 阅读
  8. 《C++新经典设计模式》之第18章 备忘录模式

    2023-12-09 23:28:02       61 阅读
  9. 考研真题数据结构

    2023-12-09 23:28:02       53 阅读
  10. 数据科学:Scipy、Scikit-Learn笔记

    2023-12-09 23:28:02       56 阅读
  11. Kotlin关键字二——constructor和init

    2023-12-09 23:28:02       64 阅读
  12. python中星号(*)的作用

    2023-12-09 23:28:02       56 阅读
  13. F. Maximum White Subtree

    2023-12-09 23:28:02       53 阅读
  14. hive sql&spark 优化

    2023-12-09 23:28:02       66 阅读