视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
详解高效而稳定的企业级.NET Office 组件Spire(.NET组件介绍之二)
2020-11-27 22:36:09 责编:小采
文档


在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是”这个系统似乎就是专门操作文档的“。毕竟现在的很多办公中大都是在PC端操作文档等软件,在这些庞大而繁重的业务中,单单依靠人力去做文档的操作需要的代价是巨大的,比如数据统计,数据分析等业务要求。这就需要我们在开发系统时,应该尽量减少使用者的一些工作量,例如将数据直接写入文档,获取网页信息后直接存为PDF保存,以便以后继续查看。软件开发的目地是对使用者便捷,但这一要求未必对开发者来说也是便捷的。

在前面介绍过一款开源免费的组件DocX,这个组件主要是对文档进行操作。另一种对Excel操作的组件NPOI组件。今天介绍一款.NET Office操作组件Spire,这是一个企业级的.NET Office操作组件,但是这是一款不免费也不开源的组件。可能很多人听到这里就不想再读下去了,的确,在国内毕竟免费才可以占用主流市场,因为很多客户希望减少成本,所以希望采用免费的工具。

作为开发者,我也会有这样的观点,不过有的时候也会思考收费与免费的工具到底哪一个好,其实这样的思考到最后似乎是没有意义的,因为事物存在既有价值,免费的可以减少成本,收费的可以获取稳定而安全的支持,各有优势和特点。任何一个软件的生成都是需要成本的,因为任何软件都是人员开发出来的,需要支付对应的成本,此处不收钱,其他的地方也会收费。无论收费与免费的哪一个好,技术总是没有错的,收费的东西,我们也可以了解,做一个技术储备。

今天要介绍的一款组件有收费的部分和免费的部分,但是这款软件的功能的确比较的强大,使用起来也比较简单,因为要收费的东西,毕竟需要做到人性化,不然谁会出钱去买,毕竟便宜而好用的东西很少。此组件的使用方式很简单,官方提供了比较完备的操作demo,所以今天的文章只做为一个引子。

由于Spire的组件较多,今天就用Spire.PDF for .NET做个引子,不一定收费就没有客户会选择,如果需要稳定的服务支持,收费的组件是可以考虑的,或者遇到土豪客户,也可以在项目中使用一下,毕竟使用起来很便捷。

一.Spire.PDF for .NET组件概述:

Spire.PDF for .NET是一个专业的PDF组件,用于在.NET应用程序中创建,编写,编辑,处理和阅读PDF文件,而不需要任何外部依赖。 使用这个.NET PDF库,您可以实现丰富的功能从头开始创建PDF文件或完全通过C#/ VB.NET处理现有的PDF文档,而无需安装Adobe Acrobat。

 .NET PDF API支持许多丰富的功能,例如安全设置(包括数字签名),PDF文本/附件/图像提取,PDF合并/拆分,元数据更新,段,图像/图像绘制和插入,表创建 以及处理和导入数据等。

此外,Spire.PDF for .NET可以应用于使用C#/ VB.NET以高质量轻松地将文本,图像和HTML转换为PDF。

以下是一个官方给出的组件解析图:

Spire.PDF for .NET支持将HTML,RTF,XPS,文本和图像转换为具有高效性能的PDF文档。 开发人员可以将PDF转换为Word,XPS,SVG,EMF,JPG,PNG,BMP,TIFF,文本格式。 此外,随着Spire.Doc for .NET和Spire.XLS for .NET,开发人员可以将Word(Doc / Docx),Excel(Xls / Xlsx)和XML转换为PDF。

此组件的功能还是非常强大的,每个开发人员都知道,产品做得不好,想要客户的钱还是很难的。看一下组件的主要功能:

1.文本格式,多语言支持,文本对齐等。

2.笔和画笔将形状元素,文本,图像绘制成PDF文档。

3.图层,透明图形,颜色空间和条形码创建可以呈现为PDF文档。

4.PDF / A-1b和PDF / x1a:2001合规性,可以应用这两种标准。

5.添加标量/矢量图像和掩码,并将它们放在指定的位置。

6.Spire.PDF for .NET可支持表和表样式

7.插入交互式元素,包括注释,操作,JavaScript,附件,书签和指定地点和外观。

以上对组件的相关背景做了一个简单的介绍,并且对组件的功能和使用情形做了简单的罗列。

二.Spire.PDF for .NET相关类的解析:

在这里主要介绍Spire的Spire.PDF组件部分,此组件有免费的和收费的两个版本,免费的版本在功能没有收费的多,但是稳定性和实用性还是较高的。我们具体看一下此组件的主要的类和方法,这里是主要介绍PDF的操作,就先看一下有关PDF的操作类和方法。

这里看以下命名空间的主要类:

以上的方法中只是操作PDF部分类,由于包含的类较多,过大的介绍篇幅就显得多余,在对PDF的操作中提供了较多的方法,因此在功能上会较为的丰富,使用起来也较为的便捷。

  1.PdfDocument类:声明PDF文档:

(1).PdfDocument类的构造函数:

public PdfDocument();
 public PdfDocument(string filename);
 public PdfDocument(byte[] bytes);
 public PdfDocument(Stream stream);
 public PdfDocument(string filename, string password);
 public PdfDocument(byte[] bytes, string password);
 public PdfDocument(Stream stream, string password);

该类提供了7个构造函数的重载版本,对应的参数类型就不做详细的介绍

(2).PdfDocument.LoadFromHTML():加载HTML页面:

 public void LoadFromHTML(string Url, bool enableJavaScript, bool enableHyperlinks, bool autoDetectPageBreak)
{
 // This item is obfuscated and can not be translated.
 PdfHtmlLayoutFormat format;
 int num;
 goto Label_001E;
Label_008F:
 num = 0;
Label_0002:
 switch (num)
 {
 case 0:
 break;

 case 1:
 if (!autoDetectPageBreak)
 {
 format.Layout = PdfLayoutType.OnePage;
 format.FitToPage = Clip.Width;
 format.FitToHtml = Clip.Height;
 num = 2;
 }
 else
 {
 num = 3;
 }
 goto Label_0002;

 case 2:
 switch ((1 == 1))
 {
 case 2:
 goto Label_008F;
 }
 if (0 != 0)
 {
 }
 break;

 case 3:
 format.Layout = PdfLayoutType.Paginate;
 format.FitToPage = Clip.Width;
 goto Label_008F;

 default:
 goto Label_001E;
 if (1 != 0)
 {
 }
 format = new PdfHtmlLayoutFormat();
 num = 1;
 goto Label_0002;
 }
 this.Sections.Add().LoadFromHTML(Url, enableJavaScript, enableHyperlinks, format);
}

2.HtmlConverter名称空间:Html转换器。

namespace Spire.Pdf.HtmlConverter
{
 public enum AspectRatio

 public enum Clip

 [ToolboxItem(false)]
 public class HtmlConverter : UserControl, sprᰐ, sprᶪ, sprṳ, sprẝ, sprẏ

 public enum ImageType

 public class PdfHtmlLayoutFormat
}

private Metafile ();
 static HtmlConverter();
 public HtmlConverter();
 public int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword);
 public HtmlToPdfResult Convert(string url, ImageType type, int width, int height, AspectRatio aspectRatio);
 public HtmlToPdfResult Convert(string html, string baseurl, ImageType type, int width, int height, AspectRatio aspectRatio);
 public HtmlToPdfResult Convert(string url, ImageType type, int width, int height, AspectRatio aspectRatio, string username, string password);
 public Image ConvertToImage(string url, ImageType type);
 public Image ConvertToImage(Stream stream, Encoding encoding, ImageType type);
 public Image ConvertToImage(string url, ImageType type, int width);
 public Image ConvertToImage(Stream stream, Encoding encoding, ImageType type, int width);
 public Image ConvertToImage(string url, ImageType type, int width, int height);
 public Image ConvertToImage(string url, ImageType type, string username, string password);
 public Image ConvertToImage(Stream stream, Encoding encoding, ImageType type, int width, int height);
 public Image ConvertToImage(string url, ImageType type, int width, int height, AspectRatio aspectRatio);
 public Image ConvertToImage(string url, ImageType type, int width, string username, string password);
 public Image ConvertToImage(Stream stream, Encoding encoding, ImageType type, int width, int height, AspectRatio aspectRatio);
 public Image ConvertToImage(string url, ImageType type, int width, int height, string username, string password);
 public Image ConvertToImage(string url, ImageType type, int width, int height, AspectRatio aspectRatio, string username, string password);
 [DispId(-5512)]
 public int CustomizeDownload();
 protected override void Dispose(bool disposing);
 public Image FromString(string html, ImageType type, int width);
 public Image FromString(string html, string baseUrl, ImageType type);
 public Image FromString(string html, ImageType type, int width, int height);
 public Image FromString(string html, string baseUrl, ImageType type, int width);
 public Image FromString(string html, ImageType type, int width, int height, AspectRatio aspectRatio);
 public Image FromString(string html, string baseUrl, ImageType type, int width, int height);
 public Image FromString(string html, string baseUrl, ImageType type, int width, int height, AspectRatio aspectRatio);
 public Image FromString(string html, string baseUrl, ImageType type, int width, int height, AspectRatio aspectRatio, string username, string password);
 public Image[] GetImagesFromString(string html, string baseUrl, ImageType type);
 public int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);int sprẏ.GetSecurityId(string pwszUrl, IntPtr pbSecurityId, ref uint pcbSecurityId, ref uint dwReserved);
 int sprẏ.GetSecuritySite(out IntPtr pSite);
 int sprẏ.GetZoneMappings(uint dwZone, out IEnumString ppenumString, uint dwFlags);
 int sprẏ.MapUrlToZone(string pwszUrl, out uint pdwZone, uint dwFlags);
 int sprẏ.ProcessUrlAction(string pwszUrl, uint dwAction, IntPtr pPolicy, uint cbPolicy, IntPtr pContext, uint cbContext, uint dwFlags, uint dwReserved);
 int sprẏ.QueryCustomPolicy(string pwszUrl, ref Guid guidKey, out IntPtr ppPolicy, out uint pcbPolicy, IntPtr pContext, uint cbContext, uint dwReserved);
 int sprẏ.SetSecuritySite(IntPtr pSite);
 int sprẏ.SetZoneMapping(uint dwZone, string lpszPattern, uint dwFlags);
 int sprᶪ.GetContainer(object ppContainer);
 int sprᶪ.GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);
 int sprᶪ.OnShowWindow(bool fShow);
 int sprᶪ.RequestNewObjectLayout();
 int sprᶪ.SaveObject();
 int sprᶪ.ShowObject();

以上是对PDF操作的相关类和方法的查看,由于此软件为商业软件,只能查看部分对外公开的代码,但是从可以查看到的代码就可以看出其内部实现的复杂度。

三.Spire.PDF for .NET实例:

   由于本文主要讲解HTML页面转换为PDF文档,所以先提供一种GET请求HTML页面,以及一种获取页面图片的操作方法。接着介绍创建PDF文档、Text转化为PDF, XPS转换为PDF,Image转换为PDF等操作方法。

1.创建HTTP的GET请求,获取网页信息:

/// <summary>
 /// 指定路径发送GET请求
 /// </summary>
 /// <param name="getUrl"></param>
 /// <returns></returns>
 public static string HttpGet(string getUrl)
 {
 try
 {
 if (string.IsNullOrEmpty(getUrl))
 throw new ArgumentNullException(getUrl);
 var request = WebRequest.Create(getUrl) as HttpWebRequest;
 if (request == null)
 return null;
 var cookieContainer = new CookieContainer();
 request.CookieContainer = cookieContainer;
 request.AllowAutoRedirect = true;
 request.Method = "GET";
 request.ContentType = "application/x-www-form-urlencoded";
 var response = request.GetResponse() as HttpWebResponse;
 if (response != null)
 {
 var instream = response.GetResponseStream();
 if (instream == null)
 throw new ArgumentNullException("getUrl");
 string content;
 using (var sr = new StreamReader(instream, Encoding.UTF8))
 {
 content = sr.ReadToEnd();
 }
 return content;
 }
 }
 catch (Exception er)
 {
 throw new Exception(er.Message);
 }
 return null;
 }

2.取得HTML中所有图片的 URL:

/// <summary> 
 /// 取得HTML中所有图片的 URL。 
 /// </summary> 
 /// <param name="url">HTML代码</param>
 /// <returns>图片的URL列表</returns> 
 public static string HtmlCodeRequest(string url)
 {
 if (string.IsNullOrEmpty(url))
 {
 throw new ArgumentNullException(url);
 }
 try
 {
 //创建一个请求
 var httprequst = (HttpWebRequest)WebRequest.Create(url);
 //不建立持久性链接
 httprequst.KeepAlive = true;
 //设置请求的方法
 httprequst.Method = "GET";
 //设置标头值
 httprequst.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
 httprequst.Accept = "*/*";
 httprequst.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
 httprequst.ServicePoint.Expect100Continue = false;
 httprequst.Timeout = 5000;
 //是否允许302
 httprequst.AllowAutoRedirect = true;
 ServicePointManager.DefaultConnectionLimit = 30;
 //获取响应
 var webRes = (HttpWebResponse)httprequst.GetResponse();
 //获取响应的文本流
 string content;
 using (var stream = webRes.GetResponseStream())
 {
 using (var reader = new StreamReader(stream, Encoding.GetEncoding("utf-8")))
 {
 content = reader.ReadToEnd();
 }
 }
 //取消请求
 httprequst.Abort();
 //返回数据内容
 return content;
 }
 catch (Exception ex)
 {
 throw new Exception(ex.Message);
 }
 }

3.创建PDF文档:

PdfDocument doc = new PdfDocument();

 doc.LoadFromHTML(url, false, true, true);

 doc.Close();

以上没有将操作组装为一个方法,由于创建操作较为简单,所以不做详细介绍,url为网页路径地址。

HtmlConverter.Convert
("http://www.wikipedia.org/","HTMLtoPDF.pdf",
 //enable javascript 
 true,
 //load timeout
* 1000,
//page size
new SizeF(612, 792),
//page margins
new PdfMargins(0, 0));

4.Text转化为PDF:

 public static void TextLayout()
 {
 //Create a pdf document.
 PdfDocument doc = new PdfDocument();

 // Create one page
 PdfPageBase page = doc.Pages.Add();
 float pageWidth = page.Canvas.ClientSize.Width;
 float y = 0;

 //page header
 PdfPen pen1 = new PdfPen(Color.LightGray, 1f);
 PdfBrush brush1 = new PdfSolidBrush(Color.LightGray);
 PdfTrueTypeFont font1 = new PdfTrueTypeFont(new Font("Arial", 8f, FontStyle.Italic));
 PdfStringFormat format1 = new PdfStringFormat(PdfTextAlignment.Right);
 String text = "Demo of Spire.Pdf";
 page.Canvas.DrawString(text, font1, brush1, pageWidth, y, format1);
 SizeF size = font1.MeasureString(text, format1);
 y = y + size.Height + 1;
 page.Canvas.DrawLine(pen1, 0, y, pageWidth, y);

 //title
 y = y + 5;
 PdfBrush brush2 = new PdfSolidBrush(Color.Black);
 PdfTrueTypeFont font2 = new PdfTrueTypeFont(new Font("Arial", 16f, FontStyle.Bold));
 PdfStringFormat format2 = new PdfStringFormat(PdfTextAlignment.Center);
 format2.CharacterSpacing = 1f;
 text = "Summary of Science";
 page.Canvas.DrawString(text, font2, brush2, pageWidth / 2, y, format2);
 size = font2.MeasureString(text, format2);
 y = y + size.Height + 6;

 //icon
 PdfImage image = PdfImage.FromFile(@"..\..\..\..\..\..\Data\Wikipedia_Science.png");
 page.Canvas.DrawImage(image, new PointF(pageWidth - image.PhysicalDimension.Width, y));
 float imageLeftSpace = pageWidth - image.PhysicalDimension.Width - 2;
 float imageBottom = image.PhysicalDimension.Height + y;

 //refenrence content
 PdfTrueTypeFont font3 = new PdfTrueTypeFont(new Font("Arial", 9f));
 PdfStringFormat format3 = new PdfStringFormat();
 format3.ParagraphIndent = font3.Size * 2;
 format3.MeasureTrailingSpaces = true;
 format3.LineSpacing = font3.Size * 1.5f;
 String text1 = "(All text and picture from ";
 String text2 = "Wikipedia";
 String text3 = ", the free encyclopedia)";
 page.Canvas.DrawString(text1, font3, brush2, 0, y, format3);

 size = font3.MeasureString(text1, format3);
 float x1 = size.Width;
 format3.ParagraphIndent = 0;
 PdfTrueTypeFont font4 = new PdfTrueTypeFont(new Font("Arial", 9f, FontStyle.Underline));
 PdfBrush brush3 = PdfBrushes.Blue;
 page.Canvas.DrawString(text2, font4, brush3, x1, y, format3);
 size = font4.MeasureString(text2, format3);
 x1 = x1 + size.Width;

 page.Canvas.DrawString(text3, font3, brush2, x1, y, format3);
 y = y + size.Height;

 //content
 PdfStringFormat format4 = new PdfStringFormat();
 text = System.IO.File.ReadAllText(@"..\..\..\..\..\..\Data\Summary_of_Science.txt");
 PdfTrueTypeFont font5 = new PdfTrueTypeFont(new Font("Arial", 10f));
 format4.LineSpacing = font5.Size * 1.5f;
 PdfStringLayouter textLayouter = new PdfStringLayouter();
 float imageLeftBlockHeight = imageBottom - y;
 PdfStringLayoutResult result
 = textLayouter.Layout(text, font5, format4, new SizeF(imageLeftSpace, imageLeftBlockHeight));
 if (result.ActualSize.Height < imageBottom - y)
 {
 imageLeftBlockHeight = imageLeftBlockHeight + result.LineHeight;
 result = textLayouter.Layout(text, font5, format4, new SizeF(imageLeftSpace, imageLeftBlockHeight));
 }
 foreach (LineInfo line in result.Lines)
 {
 page.Canvas.DrawString(line.Text, font5, brush2, 0, y, format4);
 y = y + result.LineHeight;
 }
 PdfTextWidget textWidget = new PdfTextWidget(result.Remainder, font5, brush2);
 PdfTextLayout textLayout = new PdfTextLayout();
 textLayout.Break = PdfLayoutBreakType.FitPage;
 textLayout.Layout = PdfLayoutType.Paginate;
 RectangleF bounds = new RectangleF(new PointF(0, y), page.Canvas.ClientSize);
 textWidget.StringFormat = format4;
 textWidget.Draw(page, bounds, textLayout);

 //Save pdf file.
 doc.SaveToFile("TextLayout.pdf");
 doc.Close();

 //Launching the Pdf file.
 PDFDocumentViewer("TextLayout.pdf");
 }

5.XPS转换为PDF:

public void XPStoPDF()
 {
 //xps file
 String file = @"..\..\..\..\..\..\Data\Sample4.xps";

 //open xps document
 PdfDocument doc = new PdfDocument();
 doc.LoadFromXPS(file);

 //convert to pdf file.
 doc.SaveToFile("Sample4.pdf");
 doc.Close();

 //Launching the Pdf file.
 PDFDocumentViewer("Sample4.pdf");
 }

 6.Image转换为PDF:

 public void ImageToPdf()
 {
 //Create a pdf document.
 PdfDocument doc = new PdfDocument();

 // Create one page
 PdfPageBase page = doc.Pages.Add();

 //Draw the text
 page.Canvas.DrawString("Hello, World!",
 new PdfFont(PdfFontFamily.Helvetica, 30f),
 new PdfSolidBrush(Color.Black),
 10, 10);
 //Draw the image
 PdfImage image = PdfImage.FromFile(@"..\..\..\..\..\..\Data\SalesReportChart.png");
 float width = image.Width * 0.75f;
 float height = image.Height * 0.75f;
 float x = (page.Canvas.ClientSize.Width - width) / 2;

 page.Canvas.DrawImage(image, x, 60, width, height);

 //Save pdf file.
 doc.SaveToFile("Image.pdf");
 doc.Close();

 //Launching the Pdf file.
 PDFDocumentViewer("Image.pdf");
 }

以上提供了对网站发起HTTP请求,获取网站页面信息,以及采用Spire.PDF组件创建PDF文档。如果有需要可以直接将HTTP请求获取到的信息直接加载如Spire.PDF的组件中,

由组件直接将网页信息转化为PDF文件,在这里就不再做更多的赘述,由于官方提供了很完善的demo和操作文档,在这里就不再过多的介绍使用方法。

四.总结:

 以上介绍了一款收费不开源的组件,没有更多的深入的去介绍,由于组件不开源,无法进行反编译,毕竟存在版权问题,如果需要使用到企业级的文档操作组件,并且公司不缺钱的话,可以使用一下此组件,组件的底层方法封装度较高,所以在使用的时候,开发者所需要考虑的是如何去使用组件完成功能。

   个人认为软件收费应该是趋势,毕竟任何软件都是需要投入,无论是人力成本,还是资金和时间成本。本文虽然是一篇介绍技术的文章,但是也提出了一个所有开发者都在想的问题,在项目开发中到底需不需要使用收费的软件,其实这个就是看使用环境。

下载本文
显示全文
专题