当前位置: 代码迷 >> 综合 >> work01_pdf后台打印水印
  详细解决方案

work01_pdf后台打印水印

热度:6   发布时间:2024-03-10 01:55:35.0

①. 案例演示:

  • ①. 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的文件)
    在这里插入图片描述

②. 项目实战

  • ①. 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 {
    //操作日志@AutowiredLogService 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也为1if("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). 在浏览器中打开pdfwhile ((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中的yif (height > 0) {
    height = height + 80;}for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 1) {
    //这里主要是调节pdf中的xif(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 cookieexport 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>
  相关解决方案