开源PDF工具 Apache PDFBox 认识及使用(知识点+案例)

2024-03-19 4475阅读

文章目录

  • 前言
  • 源码获取
  • 一、认识PDFBox
  • 二、导入依赖
  • 三、基础功能
    • demo1:读取pdf所有内容
    • demo2:读取所有页内容(分页)
    • demo3:添加页眉、页脚
    • demo4:添加居中45°文字水印
    • demo5:添加图片到右上角
    • 参考文章
    • 获取

      前言

      博主介绍:✌目前全网粉丝2W+,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者、专注于Java后端技术领域。

      涵盖技术内容:Java后端、算法、分布式微服务、中间件、前端、运维、ROS等。

      博主所有博客文件目录索引:博客目录索引(持续更新)

      视频平台:b站-Coder长路


      源码获取

      项目源码:Gitee、Github

      本篇文档的视频系列讲解:Java实现自动化pdf打水印工具 开源PDF工具PDFBoxWord、Word转PDF开源工具Documents4j


      一、认识PDFBox

      Apache PDFBox库是一个开源的Java工具,专门用于处理PDF文档。它允许用户创建全新的PDF文件,编辑现有的PDF文档,以及从PDF文件中提取内容。

      功能:创建、渲染、打印、合并、拆分、加密、解密、签名等多种操作PDF文件的功能,包括一个命令行工具,可以用于执行各种PDF处理任务。支持文本提取和搜索,以及将PDF转换为其他格式,如图片和文本。

      应用场景:广泛应用于企业和开发者构建PDF处理相关的应用程序和工具。

      Apache PDFBox具备以下主要功能:

      • 从PDF文件中提取Unicode文本。
      • 将单个PDF文件拆分成多个文件,或将多个PDF文件合并成一个。
      • 从PDF表单中提取数据,或填写PDF表单。
      • 验证PDF文件是否符合PDF/A-1b标准。
      • 使用标准的Java打印API打印PDF文件。
      • 将PDF文件另存为图像格式,如PNG或JPEG。
      • 从零开始创建PDF文件,包括嵌入字体和图像。
      • 对PDF文件进行数字签名。

        二、导入依赖

            
                org.apache.pdfbox
                pdfbox
                2.0.28
            
        
        

        三、基础功能

        demo1:读取pdf所有内容

        开源PDF工具 Apache PDFBox 认识及使用(知识点+案例) 第1张

        package com.changlu.demos;
        import org.apache.pdfbox.pdmodel.PDDocument;
        import org.apache.pdfbox.text.PDFTextStripper;
        import java.io.File;
        import java.net.URLDecoder;
        /**
         * @Description:
         * @Author: changlu
         * @Date: 1:28 PM
         */
        public class Demo1 {
            public static void main(String[] args) throws Exception{
                //读取resources目录下input.pdf文件
                String inputFile = URLDecoder.decode(Demo1.class.getClassLoader().getResource("input.pdf").getFile(), "UTF-8");
                PDDocument pdDocument = PDDocument.load(new File(inputFile));
                PDFTextStripper pdfTextStripper = new PDFTextStripper();
                //读取pdf中所有的文件
                String fullText = pdfTextStripper.getText(pdDocument);
                System.out.println(fullText);
            }
        }
        

        开源PDF工具 Apache PDFBox 认识及使用(知识点+案例) 第2张


        demo2:读取所有页内容(分页)

        开源PDF工具 Apache PDFBox 认识及使用(知识点+案例) 第3张

        package com.changlu;
        import org.apache.pdfbox.pdmodel.PDDocument;
        import org.apache.pdfbox.text.PDFTextStripper;
        import java.io.InputStream;
        /**
         * @Description:
         * @Author: changlu
         * @Date: 11:19 AM
         */
        public class Main {
            public static void main(String[] args) throws Exception{
                //读取resources目录下input.pdf文件
                InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
                PDDocument pdDocument = PDDocument.load(is);
                PDFTextStripper pdfTextStripper = new PDFTextStripper();
                //读取所有的分页
                for (int i = 1; i 
                    //设置起始-结束页  这里设置指定某页
                    pdfTextStripper.setStartPage(i);
                    pdfTextStripper.setEndPage(i);
                    //读取每一页
                    String pageText = pdfTextStripper.getText(pdDocument);
                    System.out.println(String.format("第%s页读取内容:", i));
                    System.out.println(pageText);
                }
            }
        }
        
            public static void main(String[] args) throws Exception{
                //读取resources目录下input.pdf文件
                InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
                PDDocument pdDocument = PDDocument.load(is);
                //自定义字体 C:\Users997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
                //URLDecoder.decode() 方法来解码 URL 编码的路径,将 %20 转换回空格
                String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
                PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
                float fontSize = 10; // 设置字体大小为12
                // 设置透明度状态对象
                PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
                graphicsState.setNonStrokingAlphaConstant(0.2f);
                graphicsState.setAlphaSourceFlag(true);
                graphicsState.setStrokingAlphaConstant(0.2f);
                //设置新的页眉
                String headerText = "咨询专转本默默学课程联系官方报名处QQ:3503851091,更多资料可加群828303961";
                String footerText = "江苏专转本公众号:专转本智慧树";
                //遍历原先的pdf文档
                for (PDPage page : pdDocument.getPages()) {
                    float pageWidth = page.getMediaBox().getWidth();
                    //计算页眉的居中位置
                    float headerTextWidth = font.getStringWidth(headerText) / 1000 * fontSize;
                    float headerCenteredX = (pageWidth - headerTextWidth) / 2; // 计算水平居中位置
                    //计算页脚的居中位置
                    float footerTextWidth = font.getStringWidth(footerText) / 1000 * fontSize;
                    float footerCenteredX = (pageWidth - footerTextWidth) / 2; // 计算水平居中位置
                    // 创建用于页眉的内容流
                    PDPageContentStream headerContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
                    headerContentStream.beginText(); // 开始文本操作
                    headerContentStream.setFont(font, fontSize); // 设置字体和字号
                    headerContentStream.newLineAtOffset(headerCenteredX, page.getMediaBox().getHeight() - 30); // 设置文本起始位置
                    headerContentStream.showText(headerText); // 绘制页眉内容
                    headerContentStream.endText(); // 结束文本操作
                    headerContentStream.close(); // 关闭内容流
                    // 添加页脚
                    PDPageContentStream footerContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
                    footerContentStream.beginText(); // 开始文本操作
                    footerContentStream.setFont(font, fontSize); // 设置字体和字号
                    footerContentStream.newLineAtOffset(footerCenteredX, 30); // 设置文本起始位置
                    footerContentStream.showText(footerText); // 绘制页脚内容
                    footerContentStream.endText(); // 结束文本操作
                    footerContentStream.close(); // 关闭内容流
                }
                //目标目录 Thread.currentThread().getContextClassLoader().getResource("").getPath()  当前工程目录路径
                //String targetPDFPath = URLDecoder.decode(Demo3.class.getClassLoader().getResource("resources").getPath() + File.separator + "output.pdf", "UTF-8");
        //        String targetPDFPath = URLDecoder.decode(Main.class.getClassLoader().getResource("output.pdf").getFile(), "UTF-8");
                String targetPDFPath = "F:\00核心知识、成果、视频产出区\技术视频\2024.2.15 自制默默学打水印工具 watermark tools\watermarkTools\src\main\resources\output.pdf";
                File outputFile = new File(targetPDFPath);
                // 若是文件存在先进行删除
                Files.deleteIfExists(Paths.get(outputFile.toURI()));
                // 保存修改后的文档
                pdDocument.save(outputFile);
                System.out.println("转换任务:" + targetPDFPath + " 成功!");
                // 关闭文档
                pdDocument.close(); // 关闭文档
            }
        }
        
            public static void main(String[] args) throws Exception{
                //读取resources目录下input.pdf文件
                InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
                PDDocument pdDocument = PDDocument.load(is);
                //自定义字体 C:\Users997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
                //URLDecoder.decode() 方法来解码 URL 编码的路径,将 %20 转换回空格
                String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
                PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
                // 设置透明度状态对象
                PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
                graphicsState.setNonStrokingAlphaConstant(0.2f);
                graphicsState.setAlphaSourceFlag(true);
                graphicsState.setStrokingAlphaConstant(0.2f);
                //设置水印名
                String waterText = "江苏专转本网课报名vx:mmxchanglu";
                //遍历原先的pdf文档
                for (PDPage page : pdDocument.getPages()) {
                    float pageWidth = page.getMediaBox().getWidth();
                    float pageHeight = page.getMediaBox().getHeight();
                    //添加水印   要求:旋转45°,不透明度30%
                    float waterTextWidth = font.getStringWidth(waterText) / 1000 * 30;
                    float waterCenteredX = (pageWidth - waterTextWidth) / 2;
                    float waterCenteredY = pageHeight / 2;
                    //创建一个水印内容流
                    PDPageContentStream waterContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
                    waterContentStream.beginText();
                    waterContentStream.setFont(font, 30);
                    // 设置不透明度
                    waterContentStream.setNonStrokingColor(0, 0, 0); // black color
                    waterContentStream.setStrokingColor(0, 0, 0); // black color
                    waterContentStream.setGraphicsStateParameters(graphicsState);//设置透明度
                    //设置旋转文本 45° 对于tx、ty是以左下角为偏移位置中心来进行旋转角度
                    waterContentStream.setTextRotation(Math.toRadians(45), 400, -50);
                    //设置文本
                    waterContentStream.newLineAtOffset(waterCenteredX, waterCenteredY);
                    waterContentStream.showText(waterText);
                    waterContentStream.endText();
                    waterContentStream.close();
                }
                //目标目录 Thread.currentThread().getContextClassLoader().getResource("").getPath()  当前工程目录路径
                String targetPDFPath = "F:\00核心知识、成果、视频产出区\技术视频\2024.2.15 自制默默学打水印工具 watermark tools\watermarkTools\src\main\resources\output.pdf";
                File outputFile = new File(targetPDFPath);
                // 若是文件存在先进行删除
                Files.deleteIfExists(Paths.get(outputFile.toURI()));
                // 保存修改后的文档
                pdDocument.save(outputFile);
                System.out.println("转换任务:" + targetPDFPath + " 成功!");
                // 关闭文档
                pdDocument.close(); // 关闭文档
            }
        }
        
            public static void main(String[] args) throws Exception{
                //读取resources目录下input.pdf文件
                InputStream is = Main.class.getClassLoader().getResourceAsStream("input.pdf");
                PDDocument pdDocument = PDDocument.load(is);
                //自定义字体 C:\Users997\Desktop\watermark tools\watermarkTools\target\classes\ttfs
                //URLDecoder.decode() 方法来解码 URL 编码的路径,将 %20 转换回空格
                String fontFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "ttfs" + File.separator + "Alibaba_PuHuiTi_2.0_65_Medium_65_Medium.ttf").getFile(), "UTF-8");
                PDType0Font font = PDType0Font.load(pdDocument, new File(fontFile));
                //遍历原先的pdf文档
                for (PDPage page : pdDocument.getPages()) {
                    float pageWidth = page.getMediaBox().getWidth();
                    float pageHeight = page.getMediaBox().getHeight();
                    //添加图片水印
                    //创建一个水印内容流
                    PDPageContentStream imageContentStream = new PDPageContentStream(pdDocument, page, PDPageContentStream.AppendMode.APPEND, true, true);
                    // 创建图像对象
        //            PDImageXObject image = PDImageXObject.createFromFile("C:\Users\93997\Desktop\watermark tools\watermarkTools\src\main\resources\images\ConsultationGroupQRCode.jpg", pdDocument);
                    String pictureFile = URLDecoder.decode(Main.class.getClassLoader().getResource(File.separator + "images" + File.separator + "ConsultationGroupQRCode.jpg").getFile(), "UTF-8");
                    PDImageXObject image = PDImageXObject.createFromFile(pictureFile, pdDocument);
                    // 计算图像的宽度和高度(缩小比例为0.3)
                    float imageWidth = (float) (image.getWidth() * 0.25);
                    float imageHeight = (float) (image.getHeight() * 0.25);
                    //具体图片位置
                    float imageX = pageWidth - imageWidth - 10;
                    float imageY = pageHeight - imageHeight - 10;
                    // 在指定位置绘制图像
                    imageContentStream.drawImage(image, imageX, imageY, imageWidth, imageHeight);
                    imageContentStream.close();
                }
                //目标目录 Thread.currentThread().getContextClassLoader().getResource("").getPath()  当前工程目录路径
                String targetPDFPath = "F:\00核心知识、成果、视频产出区\技术视频\2024.2.15 自制默默学打水印工具 watermark tools\watermarkTools\src\main\resources\output.pdf";
                File outputFile = new File(targetPDFPath);
                // 若是文件存在先进行删除
                Files.deleteIfExists(Paths.get(outputFile.toURI()));
                // 保存修改后的文档
                pdDocument.save(outputFile);
                System.out.println("转换任务:" + targetPDFPath + " 成功!");
                // 关闭文档
                pdDocument.close(); // 关闭文档
            }
        }
        

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]