Java实现给PDF文件增加背景图的操作指南

 更新时间:2025年11月27日 09:47:29   作者:何中应  
本文介绍了如何在Java中生成PDF文件并为其添加背景图,通过两种不同的方式实现:一种使用了iText库,另一种使用了PdfBox库,这两种方法都可以实现将背景图片添加到PDF文件中,并且可以根据项目需求选择合适的方法,需要的朋友可以参考下

说明:本文介绍在使用代码生成 PDF 文件的基础上,如何给生成的的 PDF 文件增加背景图。生成 PDF 文件参看下面这篇博客。

思路

思路是在生成后的 PDF 文件基础上操作,不是在生成 PDF 的模板文件上实现。

如下,是前文中生成的 PDF 文件。

将下面这张图作为文件背景放入到 PDF 文件中

实现一

如下,在原生成 PDF 文件的基础上,增加设置背景的代码

    @PostMapping("/pdf")
    public byte[] pdf() throws IOException {
        // 构建响应头
        String fileName = "example.pdf";
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentDispositionFormData("attachment", encodedFileName);

        // 生成PDF文件
        byte[] pdf = pdfService.pdf();
        // PDF文件
        File pdfFile = FileUtil.createTempFile("demo", ".pdf", null, true);
        FileUtil.writeBytes(pdf, pdfFile);
        // 背景图片
        ClassPathResource resource = new ClassPathResource("template/picture.jpg");
        File pictureFile = FileUtil.createTempFile("picture", ".jpg", null, true);
        FileUtil.writeBytes(resource.getInputStream().readAllBytes(), pictureFile);
        // 添加背景图片,获取添加背景后的PDF文件
        byte[] bytes = addBackground1(pdfFile, pictureFile);

        // 返回
        return ResponseEntity.ok()
                .headers(headers)
                .body(bytes).getBody();
    }

其中,添加背景图片方法代码如下:

    /**
     * 添加背景图片
     *
     * @param pdfFile     PDF文件
     * @param pictureFile 背景图片
     * @return 添加背景后的PDF文件
     */
    private byte[] addBackground1(File pdfFile, File pictureFile) {
        // 定义输出流,存添加完背景的PDF文件
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 透明度设置为0.2
        float transparency = 0.2f;

        // 加载PDF文件
        try (PDDocument document = PDDocument.load(pdfFile)) {
            // 加背景图片
            PDImageXObject backgroundImage = PDImageXObject.createFromFileByExtension(pictureFile, document);

            // 创建透明度配置
            PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
            graphicsState.setNonStrokingAlphaConstant(transparency);

            // 遍历每一页
            for (PDPage page : document.getPages()) {
                // 获取页面尺寸(单位:点,1点=1/72英寸)
                float pageWidth = page.getMediaBox().getWidth();
                float pageHeight = page.getMediaBox().getHeight();

                // 创建内容流(追加模式,放在最底层)
                try (PDPageContentStream contentStream = new PDPageContentStream(
                        document, page, PDPageContentStream.AppendMode.PREPEND, true)) {
                    // 应用透明度配置
                    contentStream.setGraphicsStateParameters(graphicsState);
                    // 绘制背景图(铺满整个页面)
                    contentStream.drawImage(backgroundImage, 0, 0, pageWidth, pageHeight);
                }
            }

            // 保存修改后的PDF
            document.save(outputStream);
            // 以字节数组的形式返回加完背景的PDF文件
            return outputStream.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new byte[0];
    }

这种方式所需下面这个依赖

<dependency>
	<groupId>org.apache.pdfbox</groupId>
	<artifactId>pdfbox</artifactId>
	<version>2.0.27</version>
</dependency>

实现二

还可以用下面这段代码

    /**
     * 添加背景图片
     *
     * @param pdfFile     PDF文件
     * @param pictureFile 背景图片
     * @return 添加背景后的PDF文件
     */
    private byte[] addBackground2(File pdfFile, File pictureFile) throws DocumentException, IOException {
        // 定义输出流,存添加完背景的PDF文件
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        // 透明度设置为0.2
        float transparency = 0.2f;

        PdfReader reader = null;
        PdfStamper stamper = null;
        try {
            reader = new PdfReader(FileUtil.readBytes(pdfFile));
            stamper = new PdfStamper(reader, outputStream);
            Image backgroundImage = Image.getInstance(FileUtil.readBytes(pictureFile));

            // 创建透明度配置对象
            PdfGState gState = new PdfGState();
            gState.setFillOpacity(transparency);

            int totalPages = reader.getNumberOfPages();
            for (int i = 1; i <= totalPages; i++) {
                // 直接通过PdfReader获取页面尺寸
                Rectangle pageSize = reader.getPageSize(i);
                float pageWidth = pageSize.getWidth();
                float pageHeight = pageSize.getHeight();

                backgroundImage.scaleToFit(pageWidth, pageHeight);
                backgroundImage.setAbsolutePosition(0, 0);

                PdfContentByte content = stamper.getUnderContent(i);
                // 应用透明度设置
                content.setGState(gState);
                content.addImage(backgroundImage);
            }
            stamper.close();
            reader.close();
            
            return outputStream.toByteArray();
        } catch (IOException | DocumentException e) {
            e.printStackTrace();
        } finally {
            if (stamper != null) {
                stamper.close();
            }
            if (reader != null) {
                reader.close();
            }
        }
        return new byte[0];
    }

这段代码所需下面这个依赖

<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.13.3</version>
</dependency>

效果

两种方式,实现的效果如下:

(实现一)

(实现二)

一个自适应了 PDF 文件的尺寸,一个没有,如果添加的背景图片(版权标识、企业 logo)尺寸合适的话,这两种实现方式没有大的区别。

作为开发者,可以根据当前项目中是否已引入上面哪个依赖,来选择使用哪种实现方式。

到此这篇关于Java实现给PDF文件增加背景图的操作指南的文章就介绍到这了,更多相关Java PDF文件增加背景图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一篇文章彻底搞懂面试中常被问的各种“锁”

    一篇文章彻底搞懂面试中常被问的各种“锁”

    这篇文章主要给大家介绍了关于面试中常被问的各种“锁”的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Spring中的@Pointcut切点详解

    Spring中的@Pointcut切点详解

    这篇文章主要介绍了Spring中的@Pointcut切点详解,pointcut就是切点,通知需要在哪些方法处进行增强,在AspectJ中用@Pointcut注解表达式标注,需要的朋友可以参考下
    2023-08-08
  • java版十大排序经典算法:完整代码(4)

    java版十大排序经典算法:完整代码(4)

    优秀的文章也不少,但是Java完整版的好像不多,我把所有的写一遍巩固下,同时也真诚的希望阅读到这篇文章的小伙伴们可以自己去从头敲一遍,不要粘贴复制!希望我的文章对你有所帮助,每天进步一点点
    2021-07-07
  • springmvc html资源请求404的问题解决并分析

    springmvc html资源请求404的问题解决并分析

    这篇文章主要介绍了springmvc html资源请求404的问题解决并分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Mybatis之@ResultMap,@Results,@Result注解的使用

    Mybatis之@ResultMap,@Results,@Result注解的使用

    这篇文章主要介绍了Mybatis之@ResultMap,@Results,@Result注解的使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • springboot+swagger2.10.5+mybatis-plus 入门详解

    springboot+swagger2.10.5+mybatis-plus 入门详解

    这篇文章主要介绍了springboot+swagger2.10.5+mybatis-plus 入门,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • SpringBoot异步调用相同类的解决方案

    SpringBoot异步调用相同类的解决方案

    在SpringBoot中,同一个类中调用带有@Async注解的方法时,异步调用会失效,因为直接通过this调用方法时,并没有通过Spring的代理对象,下面给大家分享SpringBoot异步调用相同类的解决方案,感兴趣的朋友一起看看吧
    2025-02-02
  • 重新理解Java泛型

    重新理解Java泛型

    这篇文章主要介绍了重新理解Java泛型,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • 如何实现Spring Event(异步事件)

    如何实现Spring Event(异步事件)

    这篇文章主要介绍了如何实现Spring Event(异步事件)问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • MyBatis框架处理字符串相等的判断条件

    MyBatis框架处理字符串相等的判断条件

    MyBatis框架提供了灵活而强大的机制来处理SQL语句中的字符串相等判断条件,无论是简单的等值判断,还是复杂的条件逻辑,下面就来详细的介绍一下,感兴趣的可以了解一下
    2025-11-11

最新评论