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

公共类

公共属性

标题级别 对应的标题样式 汉字与数字标题对应关系

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 titleDict = new ReadOnlyDictionary(new Dictionary
		{
				{ 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 imageFormatterDict = new ReadOnlyDictionary
		(
				new Dictionary{
					{ ".jpg",default},
					{ ".jpeg",default},
					{ ".png",default},
					{ ".emf",default},
					{ ".wmf",default},
					{ ".bmp",default},
				}
		);

		protected static ReadOnlyDictionary wordFormatterDict = new ReadOnlyDictionary
		(
				new Dictionary{
					{ ".doc",default},
					{ ".docx",default}
				}
		);
		#endregion


		#region 数字与大小汉字对照标 最大可是999=》九百九十九
		protected static Dictionary numberUpCaseDict = new Dictionary()
		{
			{0,"零"},{1,"一"},{2,"二"},{3,"三"},{4,"四"},{5,"五"},
			{6,"六"},{7,"七"},{8,"八"},{9,"九"},{10,"十"}
		};
		#endregion

		#region 1-5级 标题格式规则校验与标题级别
		protected static ReadOnlyDictionary titleRegexRule
			= new ReadOnlyDictionary(new Dictionary{
				{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());
			}
		}

	}
}

核心代码

生成pdf里面相关部分 如段落(标题/文本) 表格 图片 目录 书签

using Aspose.Pdf;
using Aspose.Pdf.Annotations;
using Aspose.Pdf.Facades;
using Aspose.Pdf.Text;
using Common.Bo;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;

namespace Common.Util
{
	/// 
	/// Aspose.Pdf 
	/// 生成table  
	/// 生成段落:标题/普通文本  
	/// 生成书签  
	/// 插入图片
	/// 合并pdf
	/// 生成目录
	/// 
	public class AsposePdfUtil : CommonStyle
	{

		#region pdf里面标题级别与字体大小对照关系
		public static Dictionary numberFontDict = new Dictionary()
		{
			{1,25},{2,22},{3,19},{4,17},{5,15},{6,14.2f}
		};
		#endregion

		#region 标题对应的行展示最大字符数  标题越小 展示字符越多
		public static Dictionary numberMaxShowNumsDict = new Dictionary()
		{
			{1,18},{2,20},{3,22},{4,24},{5,26},{6,28}
		};
		#endregion

		public static ReadOnlyDictionary pdfFormatterDict = new ReadOnlyDictionary
		(
				new Dictionary{
					{ ".pdf",default},
				}
		);

		//默认字体 =》宋体
		public static Aspose.Pdf.Text.Font defaultFont = FontRepository.FindFont("SimSun");

		//pdf的宽度
		public const double pdfPageWidth = 610f;


		/// 
		/// 创建document
		/// 
		/// 
		/// 
		/// 
		public static void CreateWordDocument(string comPath, out Document comDoc)
		{
			comDoc = new Document(comPath);
		}


		/// 
		/// 创建表格
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		public static void CreateTable(Document document, IList list,
			string[] columNames, string[] propNames, Action customFunc = null, bool serialNum = false, string tableTitleRemark = null)
		{
			Type tbc = typeof(T);
			Dictionary> titleColumsDict = new Dictionary>();
			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(document, list, titleColumsDict, customFunc, serialNum, tableTitleRemark);
		}


		/// 
		/// 创建表格
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		/// 
		public static void CreateTable(Document doc, IList list, Dictionary> titleColumsDict
			 , Action customFunc = null, bool serialNum = false, string tableTitleRemark = null)
		{
			//表格不存在
			if (!list.Any())
			{
				return;
			}

			string[] columNames = titleColumsDict.Select(p => p.Key).ToArray();

			Type tbc = typeof(T);
			Page page = doc.Pages.Add();
			page.SetPageSize(pdfPageWidth, page.PageInfo.Height);//设置每个页码的大小一致
			StringBuilder _columnWidthSbf = new StringBuilder(serialNum ? "30" : "");
			int colWidth = (int)((page.GetPageRect(true).Width - (serialNum ? 50 : 0)) / columNames.Length - 2);

			foreach (var item in columNames)
			{
				_columnWidthSbf.Append($" {colWidth}");
			}
			//下面的
			int offsetTop = 30;

			//额外的信息
			if (!string.IsNullOrWhiteSpace(tableTitleRemark))
			{
				Aspose.Pdf.Table tab0 = new Aspose.Pdf.Table();
				Paragraphs paragraphs0 = page.Paragraphs;
				paragraphs0.Add(tab0);
				tab0.ColumnWidths = _columnWidthSbf.ToString();
				tab0.DefaultCellBorder = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.None, 0.1F);
				tab0.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.None, 0.1F, Aspose.Pdf.Color.FromRgb(System.Drawing.Color.White));
				tab0.Margin = new Aspose.Pdf.MarginInfo(5, 2, 2, 5);
				tab0.DefaultCellPadding = new Aspose.Pdf.MarginInfo(5, 1, 1, 2);
				tab0.Top = offsetTop;//表格上边距
				tab0.Left = 5;//表格左边距
				Aspose.Pdf.Row row0 = tab0.Rows.Add();
				var cell = row0.Cells.Add();

				TextFragment fragment1 = CreateFragment(tableTitleRemark, 10);
				//fragment1.TextState.Underline = true;
				cell.Paragraphs.Add(fragment1);
				cell.ColSpan = serialNum ? 1 + columNames.Length : columNames.Length;
				offsetTop += 42;//让下面的主表格内容有点距离
			}


			Aspose.Pdf.Table tab1 = new Aspose.Pdf.Table();
			Paragraphs paragraphs = page.Paragraphs;
			paragraphs.Add(tab1);

			tab1.ColumnWidths = _columnWidthSbf.ToString();
			tab1.DefaultCellBorder = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 0.1F);
			tab1.Border = new Aspose.Pdf.BorderInfo(Aspose.Pdf.BorderSide.All, 0.1F, Aspose.Pdf.Color.FromRgb(System.Drawing.Color.Black));
			tab1.Margin = new Aspose.Pdf.MarginInfo(5, 2, 2, 5);
			//Set the default cell padding to the MarginInfo object
			tab1.DefaultCellPadding = new Aspose.Pdf.MarginInfo(5, 1, 1, 2);
			//不能这么设置不然整个页码都被内容挤垮了
			//tab1.ColumnAdjustment = ColumnAdjustment.AutoFitToContent;
			tab1.Top = offsetTop;//表格上边距
			tab1.Left = 5;//表格左边距

			//创建第一行(表头)
			Aspose.Pdf.Row row1 = tab1.Rows.Add();
			if (serialNum)
			{
				TextFragment fragment1 = CreateFragment("序号", 11.2f);
				fragment1.TextState.FontStyle = FontStyles.Bold;
				Cell cell = row1.Cells.Add();
				cell.Paragraphs.Add(fragment1);
			}

			foreach (var item in columNames)
			{
				TextFragment fragment1 = CreateFragment(item, 11.2f);
				fragment1.TextState.FontStyle = FontStyles.Bold;
				Cell cell = row1.Cells.Add();
				cell.Paragraphs.Add(fragment1);
			}

			//创建内容
			//添加每行数据  
			for (int i = 0; i < list.Count; i++)
			{
				Aspose.Pdf.Row contentRow = tab1.Rows.Add();
				//操作序号列
				if (serialNum)
				{
					//向此单元格中添加内容  
					TextFragment fragment1 = CreateFragment((i + 1).ToString(), 10.2f);
					//fragment1.TextState.HorizontalAlignment = HorizontalAlignment.Left;
					Cell cell = contentRow.Cells.Add();
					cell.Paragraphs.Add(fragment1);
				}

				foreach (var tcItem in titleColumsDict)
				{
					//向此单元格中添加内容  
					TextFragment fragment1 = CreateFragment(tcItem.Value.Invoke(list[i]) ?? "", 10.2f);
					//fragment1.TextState.HorizontalAlignment = HorizontalAlignment.Center;
					Cell cell = contentRow.Cells.Add();
					cell.Paragraphs.Add(fragment1);
				}
			}
			customFunc?.Invoke(doc);
		}

		/// 
		/// create a Fragment
		/// 
		/// 
		/// 
		private static TextFragment CreateFragment(string text, float fontSize)
		{
			TextFragment fragment1 = new TextFragment(text);
			fragment1.TextState.Font = defaultFont;
			fragment1.TextState.FontSize = fontSize;
			fragment1.TextState.FontStyle = FontStyles.Regular;
			return fragment1;
		}


		/// 
		/// 当前的domBuiler操作 插入图片 ==》追加pdf内容
		/// 
		/// 
		/// 
		public static void AppendImageAndPdf(Document doc, string filePath)
		{
			//文件资源不存在 ==》不插入图片
			if (!File.Exists(filePath))
			{
				return;
			}
			//如果是pdf
			if (filePath != null && filePath.EndsWith(".pdf", StringComparison.CurrentCultureIgnoreCase))
			{
				MergePdf(doc, new Document(filePath));
			}
			else
			{
				int imgWidth2 = 0;
				int imgHeight2 = 0;
				Page page = doc.Pages.Add();
				page.SetPageSize(pdfPageWidth, page.PageInfo.Height);//设置每个页码的大小一致
				using (System.Drawing.Image image = System.Drawing.Image.FromFile(filePath))
				{
					imgWidth2 = image.Width;
					imgHeight2 = image.Height;
					//适配宽高
					AdaptWh(page, ref imgWidth2, ref imgHeight2);
					//doc.InsertImage(image, RelativeHorizontalPosition.Page, 10.0, RelativeVerticalPosition.Page, 5.0, imgWidth2, imgHeight2, WrapType.None);*/
				}
				//按页面缩放 图片
				page.AddImage(filePath, new Aspose.Pdf.Rectangle(10, 5, imgWidth2 + 10, page.GetPageRect(true).Height - 5));
			}
		}

		/// 
		/// 合并pdf
		/// 
		/// 
		/// 
		public static void MergePdf(Document mainDoc, Document mergeDoc)
		{
			#region 搜索页码  将页码信息置空
			TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber("[—第]\\s{0,4}[0-9\\u4e00-\\u9fa5]{1,6}\\s{0,4}[—页]");
			TextSearchOptions textSearchOptions = new TextSearchOptions(true);
			textFragmentAbsorber.TextSearchOptions = textSearchOptions;
			mergeDoc.Pages.Accept(textFragmentAbsorber);
			TextFragmentCollection textFragmentCollection = textFragmentAbsorber?.TextFragments;
			if (textFragmentCollection != null)
			{
				foreach (TextFragment textFragment in textFragmentCollection)
				{
					textFragment.Text = "";
				}
			}
			#endregion
			mainDoc.Pages.Add(mergeDoc.Pages);
		}


		/// 
		/// 插入自定义标题 (实际是操作书签)
		/// 
		/// 
		/// 
		/// 
		/// 插入新的一页  一般为true是防止图片把文字覆盖了
		/// 额外的样式
		/// 是否是1-5级标题 如果 字体加粗
		public static void InsertDefinedTitle(Document doc, string title, int titleLevel, bool newPage = true, bool isTitle = true)
		{
			if (isTitle)
			{
				//此处防止titleLevel设置错误 校验纠正
				foreach (var regRule in titleRegexRule)
				{
					if (regRule.Key.IsMatch(title))
					{
						titleLevel = regRule.Value;
						break;
					}
				}
			}

			Page page;
			if (newPage || doc.Pages.Count == 0)
			{
				page = doc.Pages.Add();
				page.SetPageSize(pdfPageWidth, page.PageInfo.Height);//设置每个页码的大小一致
			}
			else
			{
				page = doc.Pages[doc.Pages.Count];
			}
			//上边距140px 默认
			double marginTop = 140;

			TextFragmentAbsorber textFragmentAbsorber = new TextFragmentAbsorber();
			page.Accept(textFragmentAbsorber);
			TextFragmentCollection textFragmentCollection = textFragmentAbsorber.TextFragments;
			if (textFragmentCollection?.Count > 0)
			{
				//如果存在了段落 向下进行一定的偏移 防止重叠
				marginTop = page.PageInfo.Height - textFragmentCollection[textFragmentCollection.Count].Position.YIndent;
			}

			#region 创建段落文本
			TextBuilder builder = new TextBuilder(page);
			//Create text paragraph
			TextParagraph paragraph = new TextParagraph();
			paragraph.HorizontalAlignment = HorizontalAlignment.Center;
			paragraph.VerticalAlignment = VerticalAlignment.Top;
			paragraph.Margin.Left = 50;//左边距50px
			paragraph.Margin.Top = marginTop;

			//paragraph.SubsequentLinesIndent = 20;
			//paragraph.Rectangle = new Aspose.Pdf.Rectangle(100, 300, 200, 700);
			// 指定换行模式
			paragraph.FormattingOptions.WrapMode = TextFormattingOptions.WordWrapMode.DiscretionaryHyphenation;
			//TextBuilderInfo textBuilderInfo = new TextBuilderInfo(builder, paragraph);

			#region  防止换行 中间多了间隔符
			int v = title.Length / numberMaxShowNumsDict[titleLevel];
			int rest = title.Length % numberMaxShowNumsDict[titleLevel];
			StringBuilder _sbf = new StringBuilder();
			//
			for (int i = 0; i < titleLevel - 1; i++)
			{
				paragraph.SubsequentLinesIndent = i * 2;
			}

			for (int i = 0; i < v; i++)
			{
				_sbf.Append(title.Substring(numberMaxShowNumsDict[titleLevel] * i, numberMaxShowNumsDict[titleLevel]));
				_sbf.Append("\r\n");
			}
			_sbf.Append(title.Substring(title.Length - rest, rest));
			#endregion

			TextFragment fragment1 = new TextFragment(_sbf.ToString());
			fragment1.TextState.Font = defaultFont;
			fragment1.TextState.FontSize = numberFontDict[titleLevel] - 1;
			fragment1.TextState.FontStyle = isTitle ? FontStyles.Bold : FontStyles.Regular;
			// 将片段添加到段落
			paragraph.AppendLine(fragment1);
			// 添加段落
			builder.AppendParagraph(paragraph);
			#endregion

			#region 创建书签
			if (isTitle)
			{
				AddMarkBook(doc, title, page);
			}
			#endregion
		}

		public static void AddMarkBook(Document doc, string title, Page page)
		{
			OutlineItemCollection pdfOutline = new OutlineItemCollection(doc.Outlines);
			pdfOutline.Title = title;
			pdfOutline.Italic = true;
			pdfOutline.Bold = true;
			// Set the destination page number
			pdfOutline.Action = new GoToAction(doc.Pages[page.Number]);
			// Add bookmark in the document's outline collection.
			doc.Outlines.Add(pdfOutline);
		}


		/// 
		/// 图片适配(页面宽高)
		/// 
		/// 
		/// 
		public static void AdaptWh(Page curPage, ref int imgWidth, ref int imgHeight)
		{
			int maxWidth = (int)(curPage.PageInfo.Width * 0.92);
			int maxHeight = (int)(curPage.PageInfo.Height * 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;
			}
		}


		/// 
		/// 创建目录---生成完毕以后  使用书签进行生成对应目录
		/// 
		/// 定位的页面,如果addPage 为true则是在此位置插入一个新页 
		/// 如果为true为新增一页并在里面创建目录(非必填)
		/// 如果需要在最上方插入书签(非必填)
		public static PdfBookmarkEditor CreateToc(Document doc, int positionPage = 1, bool addPage = true, string firstBookMark = null)
		{
			//默认访问 PDF 文件的第一页
			Page tocPage;

			if (addPage)
			{
				//在指定位置插入一页
				tocPage = doc.Pages.Insert(positionPage);
			}
			else
			{
				//在指定位置操作
				tocPage = doc.Pages[positionPage];
			}

			//创建对象来表示 TOC 信息
			TocInfo tocInfo = new TocInfo();

			TextFragment title = new TextFragment("目录");
			title.TextState.Font = defaultFont;
			title.TextState.FontSize = 24;
			title.TextState.FontStyle = FontStyles.Bold;
			//设置目录标题
			tocInfo.Title = title;
			tocPage.TocInfo = tocInfo;
			//创建将用作目录元素的字符串对象
			PdfBookmarkEditor bookmarkEditor = new PdfBookmarkEditor();
			bookmarkEditor.BindPdf(doc);
			Aspose.Pdf.Facades.Bookmarks bookmarks = bookmarkEditor.ExtractBookmarks();
			int index = 0;
			foreach (Aspose.Pdf.Facades.Bookmark bookmark in bookmarks)
			{
				//创建标题对象  目录级别
				Aspose.Pdf.Heading heading2 = new Aspose.Pdf.Heading(1);
				heading2.TextState.Font = defaultFont;
				heading2.TextState.FontSize = 9.3f;
				heading2.TextState.LineSpacing = 5;
				heading2.TextState.WordSpacing = 2;
				heading2.TextState.FontStyle = FontStyles.Regular;
				heading2.IsAutoSequence = false;
				heading2.IsInLineParagraph = false;
				heading2.HorizontalAlignment = HorizontalAlignment.Left;
				//TextFragment
				TextSegment segment2 = new TextSegment();
				heading2.TocPage = tocPage;

				#region 2-4级菜单 首行缩进
				foreach (var regRule in titleRegexRule)
				{
					if (regRule.Key.IsMatch(bookmark.Title))
					{
						StringBuilder sb = new StringBuilder();
						for (int i = 1; i < regRule.Value; i++)
						{
							sb.Append("  ");//首行缩进
						}
						segment2.Text = sb.ToString() + bookmark.Title;
						break;
					}
				}

				//没有匹配
				if (string.IsNullOrEmpty(bookmark.Title))
				{
					segment2.Text = bookmark.Title;
				}
				#endregion

				//进行换行操作
				if (segment2.Text?.Length > 50)
				{
					segment2.Text = segment2.Text.Insert(50, "\r\n");
				}

				heading2.Segments.Add(segment2);
				//指定标题对象的目标页面
				heading2.DestinationPage = doc.Pages[bookmark.PageNumber];
				//目的地页面
				heading2.Top = doc.Pages[bookmark.PageNumber].Rect.Height;
				//将标题添加到包含目录的页面
				tocPage.Paragraphs.Add(heading2);
			}

			if (!string.IsNullOrEmpty(firstBookMark))
			{
				Aspose.Pdf.Facades.Bookmarks bookmarks2 = bookmarkEditor.ExtractBookmarks();
				List bookMarkList = new List() { new Bookmark { Action = "GoTo", Title = firstBookMark, PageNumber = 1 } };
				foreach (var item in bookmarks2)
				{
					bookMarkList.Add(new Bookmark
					{
						Action = item.Action,
						Title = item.Title,
						PageDisplay = item.PageDisplay,
						PageNumber = item.PageNumber,
					});
				}

				bookmarkEditor.DeleteBookmarks();
				foreach (var item in bookMarkList)
				{
					bookmarkEditor.CreateBookmarks(item);
				}
			}

			return bookmarkEditor;
		}


		/// 
		/// 创建页码
		/// 
		public static void CreatePageNumber(Document doc, int startingNumber = 1)
		{
			// 创建页码
			PageNumberStamp pageNumberStamp = new PageNumberStamp();
			pageNumberStamp.Background = false;
			pageNumberStamp.Format = "第 # 页";
			pageNumberStamp.BottomMargin = 10;
			pageNumberStamp.HorizontalAlignment = HorizontalAlignment.Center;
			pageNumberStamp.StartingNumber = startingNumber;//默认起始页是第一页
			pageNumberStamp.TextState.Font = FontRepository.FindFont("SimSun");//宋体
			pageNumberStamp.TextState.FontSize = 10F;
			pageNumberStamp.TextState.FontStyle = FontStyles.Regular;
			pageNumberStamp.TextState.ForegroundColor = Aspose.Pdf.Color.Black;
			foreach (Aspose.Pdf.Page page in doc.Pages)
			{
				//page.SetPageSize(pdfPageWidth, page.PageInfo.Height);//设置每个页码的大小一致
				page.AddStamp(pageNumberStamp);
			}
		}


		/// 
		/// 转化成pdf并合并到主pdf结构里面
		/// 
		/// 
		/// 
		/// 
		public static void ConvertAndMergePdf(Document doc, Document mergePdfFile, Aspose.Words.Document comDoc,bool deleteMergeFile =false)
		{
			//合并当前word转化的pdf
			MergePdf(doc, mergePdfFile);
			if (deleteMergeFile)
			{
				File.Delete(mergePdfFile.FileName);
			}
		}

	}
}


你可能感兴趣的:(c#,c#,pdf,.netcore,aspose.pdf,.net)