java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java PDF文件增加背景图

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

作者:何中应

本文介绍了如何在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文件增加背景图内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文