导出pdf 加密、加水印、加页脚

1.依赖

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.10</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.65</version>
        </dependency>
 

2.工具类 

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import lombok.SneakyThrows;

import java.io.IOException;

public class PdfPageSongTiUtil extends PdfPageEventHelper {

    /**
     * 文档字体大小,页脚页眉最好和文本大小一致
     */
    public int presentFontSize = 10;

    /**
     * 文档页面大小,最好前面传入,否则默认为A4纸张
     */
    public Rectangle pageSize = PageSize.A4;

    // 模板
    public PdfTemplate total;

    // 基础字体对象
    public BaseFont bf = null;

    // 利用基础字体生成的字体对象,一般用于生成中文文字
    public Font fontDetail = null;

    /**
     *
     *  无参构造方法.
     *
     */
    public PdfPageSongTiUtil() {

    }

  
    public PdfPageSongTiUtil(int presentFontSize, Rectangle pageSize) {
        this.presentFontSize = presentFontSize;
        this.pageSize = pageSize;
    }

    public void setPresentFontSize(int presentFontSize) {
        this.presentFontSize = presentFontSize;
    }

    /**
     *
     * 文档打开时创建模板
     */
    @Override
    public void onOpenDocument(PdfWriter writer, Document document) {
    	// 共 页 的矩形的长宽高
        total = writer.getDirectContent().createTemplate(50, 50);
    }

    /**
     *
     *关闭每页的时候,写入页眉
     */
    @SneakyThrows
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        this.addPage(writer, document);
    }

    //加分页
    public void addPage(PdfWriter writer, Document document) throws IOException, DocumentException {
        //设置分页页眉页脚字体
        try {
            if (bf == null) {
                bf = BaseFont.createFont("template/GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            }
            if (fontDetail == null) {
                fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 1.写入页眉
//        ColumnText.showTextAligned(writer.getDirectContent(),
//                Element.ALIGN_LEFT, new Phrase(header, fontDetail),
//                document.left(), document.top() + 20, 0);
        // 2.写入前半部分的 第 X页/共
        Phrase footer = new Phrase("来源:中学生统一服务平台", fontDetail);

        // 4.拿到当前的PdfContentByte
        PdfContentByte cb = writer.getDirectContent();

        // 5.写入页脚1,x轴就是(右margin+左margin + right() -left()- len)/2.0F
        ColumnText
                .showTextAligned(
                        cb,
                        Element.ALIGN_CENTER,
                        footer,
                        document.right()-document.rightMargin()-5 ,
                        document.bottom() - 10, 0);
        // 调节模版显示的位置


        //加水印
        addWatermark(writer);

    }


    /**
     *
     * 关闭文档时,替换模板,完成整个页眉页脚组件
     */
    @Override
    public void onCloseDocument(PdfWriter writer, Document document) {
        // 关闭文档的时候,将模板替换成实际的 Y 值
        total.beginText();
        // 生成的模版的字体、颜色
        total.setFontAndSize(bf, presentFontSize);
        //页脚内容拼接  如  第1页/共2页
        //String foot2 = " " + (writer.getPageNumber()) + " 页";
        //页脚内容拼接  如  第1页/共2页
        String foot2 = String.valueOf(writer.getPageNumber());
        // 模版显示的内容
        total.showText(foot2);
        total.endText();
        total.closePath();
    }




    // 加水印
    public void addWatermark(PdfWriter writer) throws IOException, DocumentException {

            PdfContentByte waterMar = writer.getDirectContentUnder();
            String text="全国中学生会议";
            waterMar.beginText();
            PdfGState gs=new PdfGState();
            //透明度
            gs.setFillOpacity(0.2F);
            waterMar.setFontAndSize(BaseFont.createFont("template/GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED),12);
            waterMar.setGState(gs);
            for (int x = 0; x <=800; x+=200) {
                for (int y = 0; y < 800; y+=100) {
                    //水印对齐方式 水印内容 x坐标 y坐标 旋转角度
                    waterMar.showTextAligned(Element.ALIGN_RIGHT,text,x,y,35);
                }
            }
            waterMar.setColorFill(BaseColor.GRAY);
            waterMar.endText();
            waterMar.stroke();
        }





}

3.实体类

@Data
public class PersonnelInfo {
	private String name;

	private String phoneNumber;

	private String sex;

	private String schoolName;

	private String workerPosition;

	private String workerDate;

	private String certificate;

	private String OtherCertificate;


}

4. 例子


    @GetMapping(value = "/createFilePdf", produces = MediaType.APPLICATION_JSON_VALUE)
    public void createFilePdf(HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException {
        request.getSession();
        response.setContentType("application/pdf;charset=UTF-8");
        response.setCharacterEncoding("utf-8");
        String fileName =URLEncoder.encode( "导出pdf人员登记表","UTF-8");
        response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName+".pdf");

        List<PersonnelInfo> list=new ArrayList<>();
        PersonnelInfo personnel=new PersonnelInfo();
        personnel.setName("张三");
        personnel.setSex("男");
        personnel.setPhoneNumber("1101001001");
        personnel.setSchoolName("清华附中");
        personnel.setWorkerPosition("北京");
        personnel.setWorkerDate("1999-12-12");
        personnel.setCertificate("特级数学老师");
        personnel.setOtherCertificate("二级心理咨询");
        list.add(personnel);


        // 定义全局的字体静态变量
        Font content = null;
        Font fontHead = null;
        try {
            // 不同字体(这里定义同一种字体:包含不同字号、不同style)
            BaseFont bfChinese = BaseFont.createFont("template/GB2312.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            content = new Font(bfChinese, 11, Font.NORMAL);
            //使用字体并给出颜色
            fontHead = new Font(bfChinese,20,Font.BOLD,BaseColor.BLACK);

        } catch (Exception e) {
            e.printStackTrace();
        }


        Document document=new Document(new RectangleReadOnly(850F,590F));
        document.setMargins(50,50,45,45);

        PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
        //用户密码  保证不能修改 设置所有者密码即可
        String pwdUser="";
        //所有者密码
        String pwdOwn="18956723.";
        writer.setEncryption("".getBytes(),pwdOwn.getBytes(),PdfWriter.ALLOW_PRINTING,PdfWriter.ENCRYPTION_AES_128);
        //添加页脚、水印等
        PdfPageSongTiUtil myHeadFooter=new PdfPageSongTiUtil();
        writer.setPageEvent(myHeadFooter);
        //open
        document.open();

        Paragraph paragraphHead1=new Paragraph("人员信息列表",fontHead);
        paragraphHead1.setAlignment(Element.ALIGN_CENTER);
        document.add(paragraphHead1);
        document.add(new Paragraph("\n"));

        PdfPCell cellBg[]=new PdfPCell[2];
        float[] width={35f,30f};
        //创建表格
        PdfPTable table=new PdfPTable(width);
        table.setWidthPercentage(100.0f);

        //表格顶端文本
        PdfPCell celltTableTop[]=new PdfPCell[2];
        float[] widthTop={55f,15f};
        PdfPTable tableTop=new PdfPTable(widthTop);
        tableTop.setWidthPercentage(100.0f);
        celltTableTop[0]=new PdfPCell(new Paragraph("会议开班负责人(签字):",content));
        celltTableTop[0].setBorder(0);
        tableTop.addCell(celltTableTop[0]);
        celltTableTop[1]=new PdfPCell(new Paragraph("日期:",content));
        celltTableTop[1].setBorder(0);
        tableTop.addCell(celltTableTop[1]);
        document.add(tableTop);

        //数据列
        PdfPCell cell=null;
        //11列  人员表头
        float[] width2={10f,15f,10f,20f,25f,25f,25f,25f,25f};
        PdfPTable tabl2=new PdfPTable(width2);
        PdfPTableHeader pdfPTableHeader=new PdfPTableHeader();
        tabl2.setSpacingBefore(5f);
        tabl2.setWidthPercentage(100.0f);
        //表头  换页显示
        tabl2.setHeaderRows(1);
        tabl2.getDefaultCell().setHorizontalAlignment(1);

        List<String> listTitle=Arrays.asList("序号","姓名","性别","联系方式","工作地点","工作岗位","入职日期","教学相关资格证书","其他相关资质证书");
        for (String title : listTitle) {
            tabl2.addCell(createCell(title,content));
        }

        int   index=0;
        for (PersonnelInfo personnelInfo : list) {
            index++;
            PdfPCell cel1=new PdfPCell(new Paragraph(String.valueOf(index),content));
            PdfPCell cel2=new PdfPCell(new Paragraph(personnelInfo.getName(),content));
            PdfPCell cel3=new PdfPCell(new Paragraph(personnelInfo.getSex(),content));
            PdfPCell cel4=new PdfPCell(new Paragraph(personnelInfo.getPhoneNumber(),content));
            PdfPCell cel5=new PdfPCell(new Paragraph(personnelInfo.getSchoolName(),content));
            PdfPCell cel6=new PdfPCell(new Paragraph(personnelInfo.getWorkerPosition(),content));
            PdfPCell cel7=new PdfPCell(new Paragraph(personnelInfo.getWorkerDate(),content));
            PdfPCell cel8=new PdfPCell(new Paragraph(personnelInfo.getCertificate(),content));
            PdfPCell cel9=new PdfPCell(new Paragraph(personnelInfo.getOtherCertificate(),content));
            cel1.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel1.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel2.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel2.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel3.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel3.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel4.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel4.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel5.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel5.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel6.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel6.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel7.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel7.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel8.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel8.setHorizontalAlignment(Element.ALIGN_CENTER);

            cel9.setVerticalAlignment(Element.ALIGN_MIDDLE);
            cel9.setHorizontalAlignment(Element.ALIGN_CENTER);
            tabl2.addCell(cel1);
            tabl2.addCell(cel2);
            tabl2.addCell(cel3);
            tabl2.addCell(cel4);
            tabl2.addCell(cel5);
            tabl2.addCell(cel6);
            tabl2.addCell(cel7);
            tabl2.addCell(cel8);
            tabl2.addCell(cel9);

        }
        document.add(tabl2);


        Paragraph paragraphEnd1=new Paragraph("会议结束负责人签字:",content);
        paragraphEnd1.setIndentationLeft(460);
        paragraphEnd1.setSpacingBefore(10f);
        document.add(paragraphEnd1);

        //close
        document.close();

    }



 /**
     *
     * @param cont  表头
     * @param font  字体
     * @return
     */
   static  PdfPCell createCell(String cont,Font font){
       PdfPCell cell=new PdfPCell(new Paragraph(cont,font));
       cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
       cell.setHorizontalAlignment(Element.ALIGN_CENTER);
       cell.setFixedHeight(30);
       cell.setBackgroundColor(new BaseColor(153,203,255));
       return cell;

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/367143.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024美赛ABCDEF题成品参考论文+配套数据代码+参考文献

社区抗灾能力综合评估与决策模型研究&#xff08;其余题目都在文末&#xff09; 摘要&#xff1a;社区抗灾能力的提升对于灾害风险管理至关重要。本研究基于机器学 习方法&#xff0c;构建了社区抗灾能力预测模型&#xff0c;以评估社区在灾害事件中的表现。首先&#xff0c; 我…

20240202在WIN10下使用whisper.cpp

20240202在WIN10下使用whisper.cpp 2024/2/2 14:15 【结论&#xff1a;在Windows10下&#xff0c;确认large模式识别7分钟中文视频&#xff0c;需要83.7284 seconds&#xff0c;需要大概1.5分钟&#xff01;效率太差&#xff01;】 83.7284/4200.1993533333333333333333333333…

断路精灵:探秘Sentinel熔断策略的神奇效果

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 断路精灵&#xff1a;探秘Sentinel熔断策略的神奇效果 前言熔断策略基础&#xff1a;数字断路精灵的初见熔断策略的基本原理&#xff1a;简单示例演示熔断策略的基本用法&#xff1a; 慢调用比例熔断策…

STM32之IIC总线控制ATC24C04

一、存储器介绍 1、电子密码存储概述 单片机的电子密码存储是一种将密码信息以电子形式存储在单片机内部的技术。它通常用于需要保护敏感信息或限制访问权限的应用程序&#xff0c;如安全系统、门禁系统、电子锁等。 电子密码存储可以通过多种方式实现&#xff0c;以下是其中…

代码随想录算法训练营第二十四天| 77. 组合。

77. 组合 题目链接&#xff1a;组合 题目描述&#xff1a; 给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 解题思路&#xff1a; 本题是经典的回溯法解决的组合问题&#xff0c;回溯问题搞清楚纵向递归横向遍历即…

网络安全之SSL证书加密

简介 SSL证书是一种数字证书&#xff0c;遵守SSL协议&#xff0c;由受信任的数字证书颁发机构&#xff08;CA&#xff09;验证服务器身份后颁发。它具有服务器身份验证和数据传输加密的功能&#xff0c;能够确保数据在传输过程中的安全性和完整性。 具体来说&#xff0c;SSL证…

贝叶斯的缺点

贝叶斯方法是一种统计学习方法&#xff0c;通过利用贝叶斯定理来计算给定先验概率的情况下&#xff0c;后验概率的条件概率。虽然贝叶斯方法在许多领域中应用广泛且有效&#xff0c;但也存在一些缺点。以下是一些贝叶斯方法的缺点的例子&#xff1a; 1、先验概率的选择 贝叶斯方…

混合攻击流量对系统安全性的综合评估

很多针对安全设备的测试仅仅针对安全设备本身的防护&#xff0c;比如防御的漏洞攻击行为、恶意代码是否足够多&#xff0c;能否抵御大流量的L23层DDoS或者应用层的DDoS攻击&#xff0c;却没有考虑是否防御攻击时&#xff0c;一并阻止了正常的业务流量。以下图为例&#xff0c;当…

分享一个WPF项目

最近在学习WPF开发方式&#xff0c;找到一些项目进行拆解学习&#xff1b;本位主要分享一个WPF项目&#xff0c;叫做WPFDevelopers&#xff0c;在git上大约有1.3K星&#xff0c;话不多说&#xff0c;先看看效果&#xff1a; 这个项目开发可以编译启动后直接查看样例、Xaml、Cha…

VSCode开发常用扩展记录

1、Chinese 2、document this 可以自动为ts和js文件生成jsDoc注释 3、ESLint 能够查找并修复js代码中的问题 4、koroFileHeader 5、Prettier 代码格式化

分别用JavaScript,Java,PHP,C++实现桶排序的算法(附带源码)

桶排序是计数排序的升级版。它利用了函数的映射关系&#xff0c;高效与否的关键就在于这个映射函数的确定。为了使桶排序更加高效&#xff0c;我们需要做到这两点&#xff1a; 在额外空间充足的情况下&#xff0c;尽量增大桶的数量使用的映射函数能够将输入的 N 个数据均匀的分…

获取真实 IP 地址(二):绕过 CDN(附链接)

一、DNS历史解析记录 DNS 历史解析记录指的是一个域名在过去的某个时间点上的DNS解析信息记录。这些记录包含了该域名过去使用的IP地址、MX记录&#xff08;邮件服务器&#xff09;、CNAME记录&#xff08;别名记录&#xff09;等 DNS 信息。DNS 历史记录对于网络管理员、安全研…

虹科技术丨一文详解IO-Link Wireless技术如何影响工业无线自动化

来源&#xff1a;虹科工业智能互联 虹科技术丨一文详解IO-Link Wireless技术如何影响工业无线自动化 原文链接&#xff1a;https://mp.weixin.qq.com/s/qVIkdeI5zzzagPd0UEkfDg 欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #工业自动化 #IO-Link Wireless #工业无…

【HarmonyOS应用开发】Web组件的使用(十三)

文章末尾含&#xff1a;Web组件抽奖案例&#xff08;ArkTS&#xff09;-示例源码下载 Web组件的使用 一、概述 相信大家都遇到过这样的场景&#xff0c;有时候我们点击应用的页面&#xff0c;会跳转到一个类似浏览器加载的页面&#xff0c;加载完成后&#xff0c;才显示这个页…

MySQL 备份恢复

1.1 MySQL日志管理 在数据库保存数据时&#xff0c;有时候不可避免会出现数据丢失或者被破坏&#xff0c;这样情况下&#xff0c;我们必须保证数据的安全性和完整性&#xff0c;就需要使用日志来查看或者恢复数据了。 数据库中数据丢失或被破坏可能原因&#xff1a; 误删除数…

Git 实战场景过程(工作总结篇)

目录 前言1. Git远程仓库建立分支&#xff0c;本地未显示1.1 问题所示1.2 知识补充 2. Git暂存内容切换分支2.1 问题所示2.2 知识补充 3. Git放弃修改数据3.1 问题所示3.2 知识补充 4. git merge合并查看差异 前言 主要总结工作中的疑惑点&#xff0c;如果你也有相应的场景&am…

Request Response 基础篇

Request & Response 在之前的博客中&#xff0c;初最初见到Request和Response对象&#xff0c;是在Servlet的Service方法的参数中&#xff0c;之前隐性地介绍过Request的作用是获取请求数据。通过获取的数据来进行进一步的逻辑处理&#xff0c;然后通过对Response来进行数…

代码随想录算法训练营第38天 | 动态规划理论基础 + 509.斐波那契数 + 70.爬楼梯 + 746.使用最小花费爬楼梯

今日任务 理论基础 509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 动态规划理论基础 理论基础&#xff1a;代码随想录 动态规划&#xff0c;英文&#xff1a;Dynamic Programming&#xff0c;简称DP&#xff0c;如果某一问题有很多重叠子问题&#xff0c;使用动态规划…

Java 正则匹配sql

文章目录 正则匹配sql表名称insert intoupdate 正则表达式什么时候要加^$ 在线正则校验 正则匹配sql表名称 insert into insert into PING_TABLE (CODE, NAME) VALUES(0, 待提交),(1, 审核中),(2, 审核通过),(3, 已驳回); regex -> insert\sinto\s(\w)\s*\(?update upda…

Enemy Rat(老鼠模型)

信息: - 模型有 1.491 个顶点。 - 纹理&#xff1a;颜色、法线、粗糙度、发射、金属、等级&#xff08;2048x2048 尺寸&#xff09; 下载&#xff1a; ​​Unity资源商店链接 资源下载链接 效果图&#xff1a;