work01_pdf后台打印水印

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: work01_pdf后台打印水印

①. 案例演示:


  • ①. pom.xml


<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itext-asian</artifactId>
        <version>5.1.1</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.1.3</version>
    </dependency>
    <!--end-->
    <!-- https://mvnrepository.com/artifact/com.itextpdf.tool/xmlworker -->
    <dependency>
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>5.5.13</version>
    </dependency>
</dependencies>


②. 测试


package com.xiaozhi.controller.water;
import java.awt.FontMetrics;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.UUID;
import javax.swing.JLabel;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
public class TestWaterPrint {
    public static void main(String[] args) throws DocumentException, IOException {
        // 要输出的pdf文件
        File desc = new File("src/main/resources/test88.pdf");
        //BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("F:/test88.pdf")));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(desc));
        File directory = new File("src/main/resources");
        String courseFile = directory.getCanonicalPath()+"\\"+"fbsl.pdf";
        System.out.println(courseFile);
        // 将pdf文件先加水印然后输出
        setWatermark(bos, courseFile, "null-admin");
    }
    /**
     *
     * @param //bos输出文件的位置
     * @param input
     *            原PDF位置
     * @param waterMarkName
     *            页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    public static void setWatermark(BufferedOutputStream bos, String input, String waterMarkName)
            throws DocumentException, IOException {
        PdfReader reader = new PdfReader(input);
        PdfStamper stamper = new PdfStamper(reader, bos);
        // 获取总页数 +1, 下面从1开始遍历
        int total = reader.getNumberOfPages() + 1;
        // 使用classpath下面的字体库
        BaseFont base = null;
        try {
                 // 内容字体
                //base = BaseFont.createFont("C:/WINDOWS/Fonts/simsun.ttc,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                base =BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
           // Font fontTitle = new Font(base, 18, Font.BOLD);
            //Font fontContent = new Font(base, 12, Font.NORMAL);
        } catch (Exception e) {
            // 日志处理
            e.printStackTrace();
        }
        // 间隔
        int interval = 15;
        // 获取水印文字的高度和宽度
        int textH = 0, textW = 0;
        JLabel label = new JLabel();
        label.setText(waterMarkName);
        FontMetrics metrics = label.getFontMetrics(label.getFont());
        textH = metrics.getHeight();
        textW = metrics.stringWidth(label.getText());
        System.out.println("textH: " + textH);
        System.out.println("textW: " + textW);
        // 设置水印透明度
        PdfGState gs = new PdfGState();
        gs.setFillOpacity(0.8f);
        gs.setStrokeOpacity(0.8f);
        Rectangle pageSizeWithRotation = null;
        PdfContentByte content = null;
        for (int i = 1; i < total; i++) {
            // 在内容上方加水印
            content = stamper.getOverContent(i);
            // 在内容下方加水印
            //content = stamper.getUnderContent(i);
            content.saveState();
            content.setGState(gs);
            // 设置字体和字体大小
            content.beginText();
//            BaseColor baseColor=new BaseColor(225,225,225);
//            content.setColorFill(baseColor);
            content.setFontAndSize(base, 20);
            // 获取每一页的高度、宽度
            pageSizeWithRotation = reader.getPageSizeWithRotation(i);
            float pageHeight = pageSizeWithRotation.getHeight();
            float pageWidth = pageSizeWithRotation.getWidth();
            // 根据纸张大小多次添加, 水印文字成30度角倾斜
            for (int height = interval + textH; height < pageHeight-30; height = height + textH * 4) {
                if(height>0){
                    height=height+80;
                }
                for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 3) {
                    content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 15);
                }
            }
            content.endText();
        }
        // 关流
        stamper.close();
        reader.close();
    }
}


③. 生成文件


(这里实现的效果是先通过resource下加载到fbsl.pdf文件,通过代码打上水印,生成一个test99.pdf的文件)


微信图片_20220106184147.png


②. 项目实战


  • ①. gradle配置文件如下:


    compile 'com.itextpdf:itextpdf:5.5.13'


②. 这里实现的效果是,拿取到resourc/pdf下的pdf,加上水印,最后直接通过io进行页面的输出


package com.devplatform.biz.web.controller.biz.operations;
import com.devplatform.biz.service.log.LogService;
import com.devplatform.common.controller.BaseController;
import com.devplatform.org.vo.IPStaffVO;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@Api(tags = "运营标准相关", value = "运营标准相关")
@Slf4j
@RestController
@RequestMapping(value = "/watermarkPdf")
public class TBizOperationPdfController extends BaseController {
    //操作日志
    @Autowired
    LogService logService;
    @ApiOperation(value = "运营标准加水印打开pdf", notes = "pdfParams是pdf的名称")
    @GetMapping("/openPdf.do")
    public void openPdf(HttpServletResponse response, HttpServletRequest request) {
        //(1). 获取到当前登录的用户名信息,得到打印水印的名称
        IPStaffVO ipStaffVO = this.getCurrentStaff(request);//当前登录人员
        String waterMarkName = "";//在pdf下打印水印的名称
        String code = ipStaffVO.getOwnerunitid();//获取到店代码
        String staffName = ipStaffVO.getStaffname();//名称
        String unitUnionName = ipStaffVO.getUnitunionname();//部门名称
        //status:1代表特约店 0表示广本
        if ("1".equals(ipStaffVO.getStatus())) {
            //超级管理员status也为1
            if("admin".equals(ipStaffVO.getStaffname())){
                waterMarkName = "null-" + staffName;
            }else{
                waterMarkName = code + "-" + staffName;
            }
        } else {
            waterMarkName = unitUnionName + "-" + staffName;
        }
        //(2). 得到resource下pdf的路径
        String pdfName = "/pdf/" + request.getParameter("pdfParams");
        InputStream in = null;
        OutputStream out = null;
        try {
            response.setContentType("application/pdf");
            in = this.getClass().getResourceAsStream(pdfName);
            out = response.getOutputStream();
            // (3). 将pdf文件先加水印然后输出
            setWatermark(out, in, waterMarkName,request,ipStaffVO);
            byte[] b = new byte[512];
            //(4). 在浏览器中打开pdf
            while ((in.read(b)) != -1) {
                out.write(b);
            }
        } catch (IOException e) {
            log.error("", e);
        } finally {
            //关流
            try {
                out.flush();
            } catch (IOException e) {
                log.error("", e);
            }
            try {
                in.close();
            } catch (IOException e) {
                log.error("", e);
            }
            try {
                out.close();
            } catch (IOException e) {
                log.error("", e);
            }
        }
    }
    /**
     * @param //bos输出文件的位置
     * @param input         原PDF位置
     * @param waterMarkName 页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    private void setWatermark(OutputStream bos, InputStream input, String waterMarkName,HttpServletRequest request,IPStaffVO ipStaffVO) {
        //创建pdf需要的读写流
        PdfReader reader=null;
        PdfStamper stamper=null;
        try{
            reader = new PdfReader(input);
            stamper = new PdfStamper(reader, bos);
            // 获取总页数 +1, 下面从1开始遍历
            int total = reader.getNumberOfPages() + 1;
            // 使用classpath下面的字体库
            BaseFont base = null;
                // 内容字体
                String name = Thread.currentThread().getContextClassLoader().getResource("fonts/SIMSUN.TTC").getPath() + ",0";
                base = BaseFont.createFont(name, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                // Font fontTitle = new Font(base, 18, Font.BOLD);
                //Font fontContent = new Font(base, 12, Font.NORMAL);
            // 间隔
            int interval = 15;
            // 获取水印文字的高度和宽度
            int textH = 0, textW = 0;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            FontMetrics metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());
            log.info("textH: " + textH);
            log.info("textW: " + textW);
            // 设置水印透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.8f);
            gs.setStrokeOpacity(0.8f);
            Rectangle pageSizeWithRotation = null;
            PdfContentByte content = null;
            for (int i = 1; i < total; i++) {
                // 在内容上方加水印
                content = stamper.getOverContent(i);
                content.saveState();
                content.setGState(gs);
                // 设置字体和字体大小
                content.beginText();
                //设置字体的颜色
                BaseColor baseColor=new BaseColor(136,136,136);
                content.setColorFill(baseColor);
                content.setFontAndSize(base, 10);
                // 获取每一页的高度、宽度
                pageSizeWithRotation = reader.getPageSizeWithRotation(i);
                float pageHeight = pageSizeWithRotation.getHeight();
                float pageWidth = pageSizeWithRotation.getWidth();
                // 根据纸张大小多次添加, 水印文字成15度角倾斜
                for (int height = interval + textH; height < pageHeight - 30; height = height + textH * 4) {
                    //这里主要是调节pdf中的y
                    if (height > 0) {
                        height = height + 80;
                    }
                for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 1) {
                    //这里主要是调节pdf中的x
                    if(width>0){
                        width=width+80;
                    }
                        content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 15);
                    }
                }
                content.endText();
            }
            //记录日志
            //log(日志信息,ip地址,操作人代码,操作人名称,业务模块,logtype,recordtype)
                logService.log("打开了有水印的pdf", request.getHeader(HTTP_X_FORWARDED_FOR), ipStaffVO.getStaffid(),
                        ipStaffVO.getStaffname(), "标准运营", "02", "02");
        } catch (DocumentException e) {
            log.error("",e);
        } catch (IOException e) {
            log.error("",e);
        } catch (Exception e) {
            log.error("",e);
        } finally {
            // 关流
            try {
                stamper.close();
            } catch (DocumentException e) {
               log.error("",e);
            } catch (IOException e) {
                log.error("",e);
            }
            reader.close();
        }
    }
}


③. 前台vue对接后台接口


<template>
    <el-container>
         <el-header class="query_params query_params_header">
         </el-header>
         <el-main>
              <table class="hovertable">
              <tr>
                  <td @click="showlnp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="lnpImg" alt="理念篇" /></div>
                    <h3>1-理念篇</h3>
                  </div>
                  </td>
                  <td @click="showzzp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="zzpImg" alt="组织篇" /></div>
                    <h3>2-组织篇</h3>
                  </div>
                  </td>
                  <td @click="showhjp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="hjpImg" alt="环境篇" /></div>
                      <h3>3-环境篇</h3>
                    </div>
                  </td>
              </tr>
              <!-- 第二行 -->
              <tr>
                  <td @click="showsjzcp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="sjzcpImg" alt="数据支持篇" /></div>
                    <h3>4-数据支持篇</h3>
                  </div>
                  </td>
                  <td @click="showgljdp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="gljdpImg" alt="管理监督篇" /></div>
                    <h3>5-管理监督篇</h3>
                  </div>
                  </td>
                  <td @click="showkhwxp()">
                    <div class="bk" onmouseover="this.style.backgroundColor='#eef3f7';" onmouseout="this.style.backgroundColor='#fff';">
                      <div><img :src="khwxpImg" alt="客户维系篇" /></div>
                    <h3>6-客户维系篇</h3>
                  </div>
                  </td>
              </tr>
              </table>
         </el-main>
         <el-footer>
         </el-footer>
    </el-container>
</template>
<script>
import lnp from "@/views/business/operations/operationquery/img/lnp.jpg"
import zzp from "@/views/business/operations/operationquery/img/zzp.jpg"
import hjp from "@/views/business/operations/operationquery/img/hjp.jpg"
import sjzcp from "@/views/business/operations/operationquery/img/sjzcp.jpg"
import gljdp from "@/views/business/operations/operationquery/img/gljdp.jpg"
import khwxp from "@/views/business/operations/operationquery/img/khwxp.jpg"
import { getToken } from '@/utils/auth' // get token from cookie
export default {
  name: 'standardsManualQuery',//标准运营查询
  components: {},
    data(){
       return{
       lnpImg:lnp,//理念篇
       zzpImg:zzp,//组织篇
       hjpImg:hjp,//环境篇
       sjzcpImg:sjzcp,//数据支持篇
       gljdpImg:gljdp,//管理监督篇
       khwxpImg:khwxp,//客户维系篇
       url:''//这里获取到https://ip:端口
       }
    },
    methods:{
        showlnp(){//理念篇
         window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=lnp.pdf");
        },
        showzzp(){//组织篇
          window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=zzp.pdf");
        },
        showhjp(){//环境篇
          window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=hjp.pdf");
        },
        showsjzcp(){//数据支持篇
          window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=sjzcp.pdf");
        },
        showgljdp(){//管理监督篇
          window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=gljdp.pdf");
        },
        showkhwxp(){//客户维系篇
          window.open("/shoa/api/biz/standardsManual/openPdf.do?usertoken="+getToken()+"&&pdfParams=khwxp.pdf");
        }
    }
}
</script>
<style scoped>
  .query_params_header{
     height:auto !important;
  }
table.hovertable {
    font-family: verdana,arial,sans-serif;
    font-size:15px;
    color:#333333;
    border-width: 1px;
    border-color: #999999;
    border-collapse: collapse;
}
  img{
    width: 150px;
    height: 190px;
    cursor:pointer;
  }
  h3{
      color: #3A0088;
  }
  .bk {
    margin: 30px;
    width: 154px;
    height: 268px;
    text-align:center;
    border:3px solid #cceff5;
  }
</style>
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
前端开发 算法 Java
1024程序员节|历经一个月总结使用java实现pdf文件的电子签字+盖章+防伪二维码+水印+PDF文件加密的全套解决方案
🍅程序员小王的博客:程序员小王的博客 🍅CSDN地址:程序员小王java 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习路线:java自学的学习路线
2234 0
1024程序员节|历经一个月总结使用java实现pdf文件的电子签字+盖章+防伪二维码+水印+PDF文件加密的全套解决方案
|
5月前
|
安全 算法 文件存储
共享资料下载,自动转PDF并添加隐形水印
云盒子企业网盘增强文件安全,支持下载时自动转PDF并加水印。管理员可配置目录规则,选择明水印、隐形水印或点阵水印。明水印直观防复制,隐形水印用于隐蔽追踪,点阵水印不影响阅读。文件格式支持度和水印类型取决于设置。此功能适用于文档安全、版权保护等场景。欲知详情或测试,访问[云盒子官网](yhz66.com)咨询客服。
124 1
|
2月前
|
算法 Java 程序员
【福利😍】2024年最新103本互联网大厂程序员编程书合集【高清文字版无水印pdf】
推荐优质编程电子书资源,涵盖Python入门、算法设计、Java高并发、Docker、机器学习等领域,适合从小白到高级开发者。书籍包括《编程小白的第一本Python入门书》、《编程珠玑》等,助你提升技能,紧跟技术前沿,在职场中脱颖而出。下载地址含国内外网盘链接,更多资源可访问资料吧网站获取。
196 0
|
3月前
|
数据安全/隐私保护 Python
Python办公自动化:给pdf加水印
Python办公自动化:给pdf加水印
46 0
|
小程序 数据安全/隐私保护 Python
Python:快速去除PDF水印
Python:快速去除PDF水印
490 0
|
数据安全/隐私保护 Python
Python3,10行代码,给pdf文件去水印,再也不用花费冤枉钱了。
Python3,10行代码,给pdf文件去水印,再也不用花费冤枉钱了。
34269 1
Python3,10行代码,给pdf文件去水印,再也不用花费冤枉钱了。
|
数据安全/隐私保护 Python
Python3,2段代码,给pdf文件添加水印,原来watermark还可以这么玩。
Python3,2段代码,给pdf文件添加水印,原来watermark还可以这么玩。
34756 1
Python3,2段代码,给pdf文件添加水印,原来watermark还可以这么玩。
|
前端开发 Java Maven
使用itext7在PDF中实现多种文字水印效果
现在网络上能搜到的itext pdf水印效果,绝大部分都是itext5的,很少有itext7的,本文就将介绍一下新版本的效果
771 1
使用itext7在PDF中实现多种文字水印效果
|
数据安全/隐私保护 Python
Python批量为PDF加水印
我们自己制作的 PDF 文件,为了避免被别人滥用,通常会加上水印。而市面上很多工具都是收费的,这无疑增加了我们的成本。 所以,我使用 Python 编写了一段加水印的代码,可以批量的为多个 PDF 文件加水印,完全是免费的,在这里分享给大家。
316 0
|
Java Linux API
SpringBoot 实现 PDF 添加水印有哪些方案
PDF(Portable Document Format,便携式文档格式)是一种流行的文件格式,它可以在多个操作系统和应用程序中进行查看和打印。在某些情况下,我们需要对 PDF 文件添加水印,以使其更具有辨识度或者保护其版权。本文将介绍如何使用 Spring Boot 来实现 PDF 添加水印的方式。
259 0