• Pdf添加水印功能


    背景

    为防止涉密文件泄露,用户预览或下载pdf文件时,需要以用户信息作为水印内容加到pdf文件中。

    实现

    附件下载/预览接口:

    /// <summary>
    /// pdf附件下载接口
    /// </summary>
    /// <param name="fileId">fileId</param>
    /// <param name="userId">用户id</param>
    /// <returns></returns>
    [HttpGet("{fileId}/{userId}")]
    [AllowAnonymous]
    public IActionResult DownloadPdfFile(string fileId,string userId)
    {
        //从Mongo中下载文件
        FileByteInfo file = this._fileService.DownloadFileStream(fileId);
        if (file == null) return Ok("文件不存在或已被删除!");
        string type = "";
        System.IO.Stream fileStream = file.FileStream;	//文件流
        string fileName = file.FileName;
        if (!string.IsNullOrWhiteSpace(userId))
        {
            //获取用户身份
            User user = this._userService.GetUser(userId);
            if (user != null)
            {
                //水印:姓名(登录名 所属部门)
                string waterMarkText = $"{user.Name}({user.Code}) {user.ParentName}";
                System.IO.Stream waterPdfStream = PDFHelper.AddWatermark(fileStream, waterMarkText);
                //pdf添加水印
                if (waterPdfStream != null)
                {
                    fileStream = waterPdfStream;
                }
            }
        }
        System.IO.Stream fbyte = fileStream;
        try
        {
            var provider = new FileExtensionContentTypeProvider();
            type = provider.Mappings[file.ContentType];
        }
        catch (KeyNotFoundException)
        {
            type = "application/x-msdownload";
        }
        return File(fbyte, type, fileName);
    }
    

    ● 根据file获取文件流,调用AddWatermark将流添加水印

    PDFHelper类:
    若出现本地调试支持,部署到docker后预览出错,可能是服务器字体问题:
    //本地调用这个配置
    BaseFont font = BaseFont.CreateFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    //docker下用这个配置
    BaseFont font = BaseFont.CreateFont("/usr/share/fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

     public static class PDFHelper
     {
         /// <summary>
         /// 添加倾斜水印
         /// </summary>
         /// <param name="pdfStream">pdf文件流</param>
         /// <param name="waterMarkName">水印字符串</param>
         /// <param name="width">页面宽度</param>
         /// <param name="height">页面高度</param>
         public static MemoryStream AddWatermark(Stream pdfStream, string waterMarkName)
         {
             PdfReader pdfReader = null;
             PdfStamper pdfStamper = null;
    
             MemoryStream outStream = new MemoryStream();
             try
             {
                 pdfStream.Position = 0;
                 pdfReader = new PdfReader(pdfStream);
                 pdfStamper = new PdfStamper(pdfReader, outStream);
                 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("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);   
                 //docker下用这个配置
                 BaseFont font = BaseFont.CreateFont("/usr/share/fonts/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);    
    
                 PdfGState gs = new PdfGState();
                 int fontSize = 28;
                 for (int i = 1; i < total; i++)
                 {
                     //在内容上方加水印 ;content = pdfStamper.GetUnderContent(i);//在内容下方加水印
                     content = pdfStamper.GetOverContent(i);
    
                     gs.FillOpacity = 0.5f;   //透明度
                     content.SetGState(gs);
                     content.SetGrayFill(0.5f);
                     //开始写入文本
                     content.BeginText();
                     content.SetColorFill(BaseColor.Blue);
                     content.SetFontAndSize(font, fontSize);
                     content.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2 + 150, height / 2 + 150, 55);
                     content.SetColorFill(BaseColor.Blue);
                     content.SetFontAndSize(font, fontSize);
                     content.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2 - 150, height / 2 - 150, 55);
                     content.EndText();
                 }
             }
             catch (Exception ex)
             {
                 Console.WriteLine($"AddWatermark error:{ex.Message}, innerException:{ex.InnerException?.Message},stack:{ex.StackTrace}");
                 outStream = null;
             }
             finally
             {
                 if (pdfStamper != null)
                     pdfStamper.Close();
                 if (pdfReader != null)
                     pdfReader.Close();
                 if (outStream != null)
                     outStream.Position = 0; //必须重置位置,再写MongoDB
             }
             return outStream;
         }
         
         /// <summary>
         /// 加图片水印
         /// </summary>
         /// <param name="inputfilepath">源文件路径</param>
         /// <param name="outputfilepath">输出路径</param>
         /// <param name="modelPicName">图片地址</param>
         /// <param name="top">图片水印top</param>
         /// <param name="left">图片水印left</param>
         /// <returns></returns>
         public static bool AddImageWatermarkPDF(string inputfilepath, string outputfilepath, string modelPicName, float top, float left)
         {
             PdfReader pdfReader = null;
             PdfStamper pdfStamper = null;
             try
             {
                 pdfReader = new PdfReader(inputfilepath);
                 int numberOfPages = pdfReader.NumberOfPages;
                 iTextSharp.text.Rectangle psize = pdfReader.GetPageSize(1);
                 float width = psize.Width;
                 float height = psize.Height;
                 pdfStamper = new PdfStamper(pdfReader, new FileStream(outputfilepath, FileMode.Create));
                 PdfContentByte waterMarkContent;
                 iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(modelPicName);
                 image.GrayFill = 20;//透明度,灰色填充
                 //image.Rotation //旋转
                 //image.RotationDegrees //旋转角度
                 //水印的位置
                 if (left < 0)
                 {
                     left = width / 2 - image.Width + left;
                 }
    
                 //image.SetAbsolutePosition(left, (height - image.Height) - top);
                 image.SetAbsolutePosition(left, (height / 2 - image.Height) - top);
                 //每一页加水印,也可以设置某一页加水印
                 for (int i = 1; i <= numberOfPages; i++)
                 {
                     //waterMarkContent = pdfStamper.GetUnderContent(i);//内容下层加水印
                     waterMarkContent = pdfStamper.GetOverContent(i);//内容上层加水印
    
                     waterMarkContent.AddImage(image);
                 }
                 return true;
             }
             catch (Exception ex)
             {
                 throw ex;
             }
             finally
             {
                 if (pdfStamper != null)
                     pdfStamper.Close();
    
                 if (pdfReader != null)
                     pdfReader.Close();
             }
         }
         /// <summary>
         /// 添加普通偏转角度文字水印 
         /// </summary>
         /// <param name="inputfilepath">源文件路径</param>
         /// <param name="outputfilepath">输出路径</param>
         /// <param name="waterMarkName">水印内容</param>
         public static void AddWordWatermark2PDF(string inputfilepath, string outputfilepath, string waterMarkName)
         {
             //PDFHelper.AddWordWatermark2PDF("F:\\pdf1.pdf", "F:\\pdf1副本.pdf", "我是水印内容");
             PdfReader pdfReader = null;
             PdfStamper pdfStamper = null;
             try
             {
                 pdfReader = new PdfReader(inputfilepath);
                 pdfStamper = new PdfStamper(pdfReader, new FileStream(outputfilepath, 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.GetUnderContent(i);
                     //content = pdfStamper.GetUnderContent(i);//在内容下方加水印
                     //透明度
                     gs.FillOpacity = 0.5f;
                     content.SetGState(gs);
                     content.SetGrayFill(0.5f);
                     //开始写入文本
                     content.BeginText();
                     //content.SetColorFill(BaseColor.LIGHT_GRAY);
                     //content.SetFontAndSize(font, 100);
                     //content.SetTextMatrix(0, 0);
                     //content.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2 - 50, height / 2 - 50, 55);
                     content.SetColorFill(BaseColor.Gray);
                     content.SetFontAndSize(font, 16);
                     content.ShowTextAligned(Element.ALIGN_CENTER, waterMarkName, width / 2 - 50, height / 2 - 50, 55);
                     content.EndText();
                 }
             }
             catch (Exception ex)
             {
                 throw ex;
             }
             finally
             {
                 if (pdfStamper != null)
                     pdfStamper.Close();
    
                 if (pdfReader != null)
                     pdfReader.Close();
             }
         }
     }
    
    

    效果图

  • 相关阅读:
    iOS获取设备唯一标识的各种方法?IDFA、IDFV、UDID分别是什么含义?
    李洪强iOS开发之FMDB线程安全的用法
    李洪强iOS开发之-FMDB的用法
    李洪强iOS开发之-sql数据库的使用
    iOS截屏功能
    李洪强和你一起学习前端之(6)css行高,盒模型,外边距
    iOS网络_优化请求性能
    iOS-ARC-环境下如何查看引用计数的变化
    远程桌面连接没有授权此用户进行远程登陆
    路由重发布
  • 原文地址:https://www.cnblogs.com/liaoshiqi/p/16382643.html
Copyright © 2020-2023  润新知