Java将多张图片合并保存到同一页PDF中

功能

使用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);
    }

}

最终效果

在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将多张图片合并到doc文件,你可以使用Apache POI库。这是一个Java开发库,用于创建和编辑Microsoft Office文档。 以下是一个简单的Java代码示例,演示如何将多张图片合并到doc文件: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.usermodel.Picture; import org.apache.poi.hwpf.usermodel.PictureType; import org.apache.poi.poifs.filesystem.POIFSFileSystem; public class MergeImagesToDoc { public static void main(String[] args) { try { // 创建一个空白的doc文件 HWPFDocument doc = new HWPFDocument(); // 循环遍历要合并图片 for (int i = 1; i <= 3; i++) { // 读取图片文件 FileInputStream stream = new FileInputStream("image" + i + ".jpg"); // 将图片插入到doc文件 Picture picture = doc.getPicturesTable().createPicture(doc.getNextPicNameNumber(), PictureType.JPEG, "image" + i + ".jpg", stream, 100, 100); // 设置图片的位置和大小 picture.setDxaGoal(100); picture.setDyaGoal(100); picture.setDxaSaved(100); picture.setDyaSaved(100); picture.setWrapType(3); // 关闭流 stream.close(); } // 将doc文件保存到磁盘上 FileOutputStream out = new FileOutputStream(new File("merged.doc")); doc.write(out); out.close(); System.out.println("合并完成!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 在此示例,我们创建了一个空白的doc文件,并使用循环遍历读取要合并图片,然后将它们插入到doc文件。最后,将doc文件保存到磁盘上。 请注意,此示例使用的是HWPFDocument类,这是Apache POI库用于操作.doc格式文件的类。如果你要操作.docx格式文件,则需要使用XWPFDocument类。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值