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

news2024/11/15 12:17:45

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;

    }

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端开发之deepmerge的使用和示例(对象的深度合并)

前端开发之deepmerge的使用和示例 前言使用场景链接效果图vue中简单案例1、安装插件2、示例结果前言 在平时的项目中经常会涉及到对象除了第一层以及下层进行深度合并,本问讲解的是深度合并的插件deepmerge,使用此插件避免通过递归实现一些深度合并所带来的问题 使用场景 …

Django的web框架Django Rest_Framework精讲(二)

文章目录 1.自定义校验功能&#xff08;1&#xff09;validators&#xff08;2&#xff09;局部钩子&#xff1a;单字段校验&#xff08;3&#xff09;全局钩子&#xff1a;多字段校验 2.raise_exception 参数3.context参数4.反序列化校验后保存&#xff0c;新增和更新数据&…

基于SpringBoot Vue超市管理系统

大家好✌&#xff01;我是Dwzun。很高兴你能来阅读我&#xff0c;我会陆续更新Java后端、前端、数据库、项目案例等相关知识点总结&#xff0c;还为大家分享优质的实战项目&#xff0c;本人在Java项目开发领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#x…

爱快安装和双宽带叠加

文章目录 一、爱快安装二、爱快使用1. 配置WAN12. 配置WAN23. 配置LAN14. 配置DHCP5. DNS设置6. 多线负载7. 基础设置 三、通过交换机拨号1. 交换机设置2. 配置WAN1 一、爱快安装 &#xff08;1&#xff09;下载爱快路由ISO版本 爱快路由系统下载 &#xff08;2&#xff09;IS…

MH-ET LIVE Boards(ATTiny88)实验一---点亮板载灯

MH-ET LIVE Boards(ATTiny88&#xff09;实验一点亮板载灯 在Arduino IDE中添加开发板资源包加入开发板json添加开发板 安装开发板驱动方法一&#xff1a;github下载2.0a4.rar方法二&#xff1a;开发板的package包中自带的2.0a4.rar安装驱动确认安装成功 blink.ino程序测试![在…

Vulnhub靶机:hacksudo1

一、介绍 运行环境&#xff1a;Virtualbox 攻击机&#xff1a;kali&#xff08;10.0.2.15&#xff09; 靶机&#xff1a;hacksudo1&#xff08;10.0.2.43&#xff09; 目标&#xff1a;获取靶机root权限和flag 靶机下载地址&#xff1a;https://www.vulnhub.com/entry/hac…

Python武器库开发-武器库篇之zip文件暴力破解(五十一)

Python武器库开发-武器库篇之zip文件暴力破解(五十一) Zip文件是一种常用的存档文件格式&#xff0c;用于将多个文件和文件夹压缩成一个单独的文件。它是一种广泛接受和支持的文件格式&#xff0c;几乎所有操作系统和计算机都能够处理Zip文件。Zip文件使用一种压缩算法来减小文…

状态流支持的状态和转换操作类型

状态操作类型 States 可以有不同的操作类型&#xff0c;包含了entry, during, exit, bind, and, on event_name 操作。状态的操作使用以下通用格式的标签表示法分配给操作类型&#xff1a; name/ entry:进入操作 during:在操作期间 exit:退出操作 bind:数据名, 事件名 on even…

使用wda框架实现IOS自动化测试详解

目录 1、weditor元素定位工具 1.1、weditor的安装和使用 2、wda iOS自动化框架 2.1、wda概述 2.2、wda安装 2.3、wda的使用 2.3.1、全局配置 2.3.2、创建客户端 2.3.3、APP相关操作 1、启动APP 2、关闭APP 3、获取APP状态信息 4、获取当前APP的运行信息 2.3.4、设…

Java自救手册

目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&#xff1a; 网络不通一般有两种情况&#xff1a; Maven 拿Maven 拿到Maven以后 Maven单独的报红 Git git注意&#xff1a; 目录 访问地址 访问地址&#xff0c;发现不通&#xff0c;无法访问&…

Python中with管理上下文

上下文管理器 上下文管理器本质就是能够支持with操作。 任何实现了 __enter__() 和 __exit__() 方法的对象都可称之为上下文管理器&#xff0c;上下文管理器对象可以使用 with 关键字。显然&#xff0c;文件&#xff08;file&#xff09;对象也实现了上下文管理器协议。 实现…

Canal 结合 SpringBoot 源码梳理

1、canal是什么&#xff0c;可以用来作什么 canal是阿里开源的一个用于监听数据库binlog&#xff0c;从而实现数据同步的工具。 2、安装 我使用的是1.1.5版本&#xff0c;太高的版本需要的jdk版本和mysql的驱动版本会更高&#xff0c;可以根据自己的环境选择。 如果是自己玩的话…

24.云原生之ArgoCD钩子

云原生专栏大纲 文章目录 Argo CD钩子如何定义钩子钩子删除策略 Argo CD钩子 Argo CD 是一个用于部署和管理 Kubernetes 应用程序的工具&#xff0c;它提供了一种声明式的方式来定义和自动化应用程序的部署过程。Argo CD 钩子&#xff08;Hooks&#xff09;是一种机制&#x…

MySQL-- if()函数 简单明了

if 主要有&#xff1a;IF函数嵌套和IF聚合函数 两类&#xff0c;主要是用来根据条件返回不同值。 基本语法为; IF(条件表达式,值1,值2)如果条件表达式为True&#xff0c;返回值1&#xff0c;为False,返回值2.返回值可以是任何值&#xff0c;比如&#xff1a;数值&#xff0c;…

消息中间件之RocketMQ源码分析(五)

消费进度保存机制 消费者启动时会同时启动位点管理器&#xff0c;RocketMQ设计了远程位点管理和本地位点管理 两种位点管理方式. 集群消费时&#xff0c;位点由客户端提交给Broker保存. 广播消费时&#xff0c;位点保存在消费者本地磁盘上 OffsetStore接口核心方法 void load(…

重写Sylar基于协程的服务器(4、协程调度模块的设计)

重写Sylar基于协程的服务器&#xff08;4、协程调度模块的设计&#xff09; 重写Sylar基于协程的服务器系列&#xff1a; 重写Sylar基于协程的服务器&#xff08;0、搭建开发环境以及项目框架 || 下载编译简化版Sylar&#xff09; 重写Sylar基于协程的服务器&#xff08;1、日…

智慧文旅:驱动文化与旅游融合发展的新动力

随着科技的快速发展和人们生活水平的提高&#xff0c;文化和旅游的融合成为了时代发展的必然趋势。智慧文旅作为这一趋势的引领者&#xff0c;通过先进的信息技术手段&#xff0c;推动文化与旅游的深度融合&#xff0c;为产业的发展注入新的活力。本文将深入探讨智慧文旅如何成…

被人疯狂吐槽的预制菜,居然是资本看重的“万亿级”市场?

被人疯狂吐槽的预制菜&#xff0c;居然是资本看重的“万亿级”市场&#xff1f; 文丨微三云营销总监胡佳东&#xff0c;点击上方“关注”&#xff0c;为你分享市场商业模式电商干货。 - 大家是不是以为只有被天天吐槽难吃的外卖和小饭店&#xff0c;才会用预制菜&#xff0c;…

【LeetCode】17. 电话号码的字母组合(中等)——代码随想录算法训练营Day25

题目链接&#xff1a;17. 电话号码的字母组合 题目描述 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 示例 1&#xff…

基于springboot校园二手书交易管理系统源码和论文

在Internet高速发展的今天&#xff0c;我们生活的各个领域都涉及到计算机的应用&#xff0c;其中包括乐校园二手书交易管理系统的网络应用&#xff0c;在外国二手书交易管理系统已经是很普遍的方式&#xff0c;不过国内的管理系统可能还处于起步阶段。乐校园二手书交易管理系统…