【无标题】

该代码示例展示了如何利用ApachePDFBox库将多张图片合并到一个PDF页面上。首先,计算总页面尺寸,然后逐个添加图片并调整位置以居中显示。最后,将生成的PDF保存为字节数组输入流。
摘要由CSDN通过智能技术生成

功能
使用Java将多张图片合并保存到同一页PDF中
依赖框架
pdfbox-2.0.19

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

代码内容


package com.fangjing.fjdemo.pdf;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
 * @author:fangjing
 * @date: Created in 14:21 2021-02-19.
 * @desc: PDF转换相关
 */
public class PdfConverterUtil {

    private PdfConverterUtil() {
        // empty method
    }

    /**
     * @desc 将多个图片放置到一个PDF页中
     * @param imageStreamList 图片流列表
     * @return 最终生成PDF流
     * @throws IOException 执行失败的异常
     */
    public static ByteArrayInputStream buildSinglePagePdfFromImage(List<BufferedImage> imageStreamList) throws IOException {
        // 页高度取所有图片的高度之和+间隔,页宽度取所有图片中最宽的一个+固定间隔*2
        // 间隔暂时取50
        int interval = 50;
        int pageHeight = interval;
        int pageWidth = 0;
        for (BufferedImage image : imageStreamList) {
            pageHeight = image.getHeight() + pageHeight + interval;
            pageWidth = Math.max(image.getWidth(), pageWidth);
        }
        pageWidth = pageWidth + interval * 2;
        try (PDDocument pdDocument = new PDDocument()) {
            // 生成单页
            PDPage pdPage = new PDPage(new PDRectangle(pageWidth, pageHeight));
            pdDocument.addPage(pdPage);
            int currentHeight = pageHeight;
            for (BufferedImage imageStream : imageStreamList) {
                currentHeight = currentHeight - imageStream.getHeight() - interval;
                try (PDPageContentStream contentStream = new PDPageContentStream(pdDocument, pdPage, PDPageContentStream.AppendMode.APPEND, false)) {
                    PDImageXObject pdImageObject = LosslessFactory.createFromImage(pdDocument, imageStream);
                    contentStream.drawImage(pdImageObject, getXCoordinate(pageWidth, imageStream.getWidth()), currentHeight, imageStream.getWidth(), imageStream.getHeight());
                }
            }
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            pdDocument.save(outputStream);
            pdDocument.close();
            return new ByteArrayInputStream(outputStream.toByteArray());
        }
    }

    /**
     * @desc 计算使图片居中的坐标
     * @param pageWidth 页面宽度
     * @param imageWidth 图片宽度
     * @return 图片应该设置的页面坐标
     */
    private static float getXCoordinate(int pageWidth, int imageWidth) {
        return new BigDecimal(pageWidth - imageWidth)
                .divide(new BigDecimal(2), RoundingMode.DOWN)
                .floatValue();
    }
}

单测

package com.fangjing.fjdemo.pdf;

import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;

/**
 * @author fangjing
 * @date 8/3/2022-9:52 PM
 * @desc Pdf转换相关单测
 */
public class PdfConverterUtilTest {

    @Test
    public void testBuildSinglePagePdfFromImage() throws IOException {
        BufferedImage imageStream1 = ImageIO.read(new URL("https://image1.com/f?raw=1"));
        BufferedImage imageStream2 = ImageIO.read(new URL("https:/image2/f?raw=1"));

        ByteArrayInputStream pdfFromImage = PdfConverterUtil.buildSinglePagePdfFromImage(Arrays.asList(imageStream1, imageStream2));
        File file = new File("test.pdf");
        FileUtils.copyInputStreamToFile(pdfFromImage, file);
        Assert.assertNotNull(pdfFromImage);
        boolean delete = file.delete();
        Assert.assertTrue(delete);
    }

}

最终效果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值