700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > Aspose iText实现给PDF添加水印功能

Aspose iText实现给PDF添加水印功能

时间:2021-05-03 00:32:25

相关推荐

Aspose iText实现给PDF添加水印功能

一、背景

最近有个项目需要实现给pdf、word、excel、图片等资源添加水印功能,最开始用的是前端来添加水印,后面发现会一点技术的还是可以通过请求捕获到你的源文件,那我加水印的意义何在?最后只能在后台直接返回已经处理过的文件,这样就不会有源文件被捕获的问题了。

好了,功能背景介绍完后,进入正题。

是怎么实现的呢?最开始想到的就是Aspose PDF.dll这个来做,因为项目中有其他地方用了Aspose,cell、Aspose,word。所以对于这个需求,第一时间想到还是Aspose。

下面就看看具体代码是怎么实现的吧。

二、实现功能

1、Aspose PDF.dll 实现PDF添加水印

/// <summary>/// pdf添加文字水印(自定义水印行数和列数)/// </summary>/// <param name="pdfStream">pdf文件流</param>/// <param name="watermarkText">水印文字</param>/// <param name="fontSize">文字大小</param>/// <param name="fontColor">文字颜色</param>/// <param name="typeface">字体:(中文水印请自行查找相应字体的英文名称,如:宋体(SimSun),黑体(SimHei),仿宋(FangSong),微软雅黑(Microsoft YaHei)等等...)</param>/// <param name="rotation">倾斜角度</param>/// <param name="opacity">不透明度(值为:0-1)</param>/// <param name="watermarkRowNum">水印行数</param>/// <param name="watermarkColumnNum">水印列数</param>/// <returns></returns>public MemoryStream AddTextWatermarkCustom(MemoryStream pdfStream, string watermarkText, float fontSize, Color fontColor, string typeface, double rotation = 0, double opacity = 0, int watermarkRowNum = 1, int watermarkColumnNum = 1){try{/*计算倾斜高度-start*/var angle = Math.Abs(rotation);var width = watermarkText.Length * fontSize;var radian = 2 * Math.PI / 360 * angle;var top = Math.Sin(radian) * width;/*计算倾斜高度-end*/Document document = new Document(pdfStream);for (int i = 1; i <= document.Pages.Count; i++){var pageWidth = document.Pages[i].GetPageRect(false).Width;var pageHeight = document.Pages[i].GetPageRect(false).Height;WatermarkArtifact artifact = new WatermarkArtifact();artifact.SetTextAndState(watermarkText, new TextState{FontSize = fontSize,ForegroundColor = fontColor,Font = FontRepository.FindFont(typeface),});artifact.Rotation = rotation;artifact.Opacity = opacity;artifact.IsBackground = false;if (watermarkRowNum == 1 && watermarkColumnNum == 1){artifact.ArtifactHorizontalAlignment = HorizontalAlignment.Center;artifact.ArtifactVerticalAlignment = VerticalAlignment.Center;document.Pages[i].Artifacts.Add(artifact);}else{artifact.ArtifactHorizontalAlignment = HorizontalAlignment.Left;artifact.ArtifactVerticalAlignment = VerticalAlignment.Top;for (int j = 1; j <= watermarkColumnNum; j++){artifact.LeftMargin = (j - 1) * (pageWidth / watermarkColumnNum) + fontSize;for (int z = 1; z <= watermarkRowNum; z++){artifact.TopMargin = (z - 1) * (pageHeight / watermarkRowNum) + top;document.Pages[i].Artifacts.Add(artifact);}}}}var outStream = new MemoryStream();document.Save(outStream, SaveFormat.Pdf);outStream.Seek(0, SeekOrigin.Begin);return outStream;}catch (Exception ex){throw ex;}}

这个方法基本网上都有,我就直接贴上来了。

所以Aspose实现给PDF加水印还是比较方便的。

但是

但是

但是

经过简单的测试就发现一个巨大的问题。

抛异常了,翻译了一下:在评估模式下最多可以查看 4 个元素(对于任何集合)。

什么玩意?百度了一下,发现我们用的Aspose是试用版,试用版有限制,最多支持4页。wnm~

怎么办呢,正式版老贵了,咋办,找破解的呗。费了老大劲找了很多资源,最后,终于

我放弃了。。。。

含泪,没有办法,没有积分,C币,网上都要积分啥的才能下载。

至此Aspose实现给PDF添加水印的功能也就这样了。最起码学习了一下。

2、iTextSharp 实现PDF添加水印

经过上面的一系列打击之后,我决定请教微信群聊里面的众多大佬。

大佬的一句itext让我打开的新的大门。我立马流利的打开浏览器,百度输入itext,研究了一下发现真的可以,而且有很多写好的文章,于是我立马起来劲头,又是一波流利的ctrl c+v。根据自己的实际场景,略加修改,就有了一下代码:

/// <summary>/// 添加水印/// </summary>/// <param name="pdfStream"></param>/// <param name="waterMarkName"></param>/// <returns></returns>public MemoryStream SetWaterMark(Stream pdfStream, string waterMarkName){try{MemoryStream outStream = new MemoryStream();PdfReader pdfReader = new PdfReader(pdfStream);PdfStamper pdfStamper = new PdfStamper(pdfReader, outStream);pdfStamper.Writer.CloseStream = false;int total = pdfReader.NumberOfPages + 1;iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);float width = psize.Width;float height = psize.Height;PdfContentByte content;BaseFont font = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);PdfGState gs = new PdfGState();for (int i = 1; i < total; i++){content = pdfStamper.GetOverContent(i);//在内容上方加水印//content = pdfStamper.GetUnderContent(i);//在内容下方加水印//透明度gs.FillOpacity = 0.3f;content.SetGState(gs);//content.SetGrayFill(0.3f);//开始写入文本content.BeginText();content.SetColorFill(BaseColor.GRAY);content.SetFontAndSize(font, 30);content.SetTextMatrix(0, 0);for (int ii = 0; ii < 5; ii++){for (int j = 0; j < 5; j++){content.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, (50.5f + ii * 350),(40.0f + j * 150), -45);}}content.EndText();}if (pdfStamper != null)pdfStamper.Close();if (pdfReader != null)pdfReader.Close();return outStream;}catch (Exception ex){throw ex;}}

看了一下代码,发现并没有什么难点。算是一眼就能看明白写的是啥,我略加修改添加了两个for循环来实现水印的重复,不然原来它就一页一个水印。

同学们如果不需要一个多个水印的,可以把for循环去掉哈。

代码借鉴完后,抱着激动的心,尝试了一下,我擦,可以,而且很快,2380多页的pdf,不到6s就导出了。可以可以。

看来微信群里面的大佬还是比较厉害的,主要自己太菜了。

哦哦,差点忘记了,调用我顺便实现了两种,提供给大家参考,虽然不算是什么牛逼的代码,但是可以省去大家写哎,ctrl c+v 不香么~~

第一种:网络地址的pdf文件加水印后直接浏览器下载

/// <summary>/// 下载水印PDF/// </summary>/// <param name="fileUrl">pdf地址</param>/// <param name="waterMarkText">水印文字</param>/// <param name="outFileName">输出文件名</param>void GetWatermark(string fileUrl, string waterMarkText, string outFileName){HttpWebRequest request = (HttpWebRequest)WebRequest.Create(fileUrl);request.Method = "GET";WebResponse response = request.GetResponse();var stream = response.GetResponseStream();var outStream = SetWaterMark(stream, waterMarkText);var fileBytes = outStream.ToArray();httpContext.Response.ContentType = "application/octet-stream";httpContext.Response.AppendHeader("Content-Disposition", "attachment;filename=" + outFileName);//文件名和格式(格式可以自己定)httpContext.Response.AddHeader("Content-Length", fileBytes.Length.ToString());//文件大小httpContext.Response.BinaryWrite(fileBytes); //放入byte[]httpContext.Response.End();httpContext.Response.Close();}

第二种:给本地pdf文件添加水印

/// <summary>/// 给本地PDF文件添加水印/// </summary>/// <param name="filePath">E:/studyHome/my_tools_project/tools_project/123.pdf</param>/// <param name="text">xxx</param>public void AddWaterMark(string filePath, string text){PdfReader pdfReader = null;PdfStamper pdfStamper = null;string tempPath = Path.GetDirectoryName(filePath) + Path.GetFileNameWithoutExtension(filePath) + "_temp.pdf";try{pdfReader = new PdfReader(filePath);pdfStamper = new PdfStamper(pdfReader, new FileStream(tempPath, FileMode.Create));int total = pdfReader.NumberOfPages + 1;iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);float width = psize.Width;float height = psize.Height;PdfContentByte content;BaseFont font = BaseFont.CreateFont(@"C:\WINDOWS\Fonts\SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);PdfGState gs = new PdfGState();for (int i = 1; i < total; i++){content = pdfStamper.GetOverContent(i);//在内容上方加水印//content = pdfStamper.GetUnderContent(i);//在内容下方加水印//透明度gs.FillOpacity = 0.3f;content.SetGState(gs);//content.SetGrayFill(0.3f);//开始写入文本content.BeginText();content.SetColorFill(BaseColor.GRAY);content.SetFontAndSize(font, 30);content.SetTextMatrix(0, 0);content.ShowTextAligned(Element.ALIGN_CENTER, text, width - 120, height - 120, -45);content.EndText();}}catch (Exception ex){throw ex;}finally{if (pdfStamper != null)pdfStamper.Close();if (pdfReader != null)pdfReader.Close();File.Copy(tempPath, filePath, true);File.Delete(tempPath);}}

好了,至此,这个功能点算是解决了,我呢也学习了不少东西

发出来给大家做个参考,也是给自己一个记录。

欢迎大家一起探讨学习。

差点忘记,给大家看看效果:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。