strongmore

简介

在项目中我们有时候会遇到操作PDF文件的需求,如将PDF的每一页转换成图片,今天我们就来实现一下相关功能。

实现

引入依赖

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

pdfbox是一个开源的操作PDF的工具包,这里是 官方文档

将PDF转换成多张图片

程序中使用的源PDF下载 阿里巴巴Java开发...1528284352.pdf

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

public class Client {

  public static void main(String[] args) throws Exception {
    testPdf2images();
  }


  private static void testPdf2images() throws Exception {
    List<byte[]> images = pdf2images(new File("D:/testpdf/阿里巴巴Java开发...1528284352.pdf"));
    AtomicInteger fileNameIndex = new AtomicInteger(1);
    for (byte[] image : images) {
      new ByteArrayInputStream(image).transferTo(
          new FileOutputStream("D:/testpdf/" + fileNameIndex.getAndIncrement() + ".png"));
    }
  }

  /**
   * 将PDF文件转换成多张图片
   *
   * @param pdfFile PDF源文件
   * @return 图片字节数组列表
   */
  private static List<byte[]> pdf2images(File pdfFile) throws Exception {
    //加载PDF
    PDDocument pdDocument = PDDocument.load(pdfFile);
    //创建PDF渲染器
    PDFRenderer renderer = new PDFRenderer(pdDocument);
    int pages = pdDocument.getNumberOfPages();
    List<byte[]> images = new ArrayList<>();
    for (int i = 0; i < pages; i++) {
      ByteArrayOutputStream output = new ByteArrayOutputStream();
      //将PDF的每一页渲染成一张图片
      BufferedImage image = renderer.renderImage(i);
      ImageIO.write(image, "png", output);
      images.add(output.toByteArray());
    }
    pdDocument.close();
    return images;
  }

}

创建的图片列表如下

将图片列表转换成PDF

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Objects;
import javax.imageio.ImageIO;
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.PDImageXObject;

public class Client2 {

  public static void main(String[] args) throws Exception {
    testImages2pdf();
  }

  private static void testImages2pdf() throws Exception {
    File file = new File("D:/testpdf");
    //过滤所有图片文件
    File[] files = file.listFiles((f, s) -> s.endsWith(".png"));
    if (Objects.nonNull(files)) {
      //根据名称排序
      Arrays.sort(files, Client2::compareImageFile);
      byte[] pdf = images2pdf(files);
      new ByteArrayInputStream(pdf).transferTo(
          new FileOutputStream("D:/testpdf/阿里巴巴java文档.pdf"));
    }
  }

  /**
   * 根据图片名称排序
   */
  private static int compareImageFile(File f1, File f2) {
    String f1Name = f1.getName();
    String f2Name = f2.getName();
    return Integer.compare(Integer.parseInt(f1Name.substring(0, f1Name.lastIndexOf("."))),
        Integer.parseInt(f2Name.substring(0, f2Name.lastIndexOf("."))));
  }

  /**
   * 根据多张图片生成PDF文件
   *
   * @param images 图片列表
   * @return PDF文件
   */
  private static byte[] images2pdf(File... images) throws Exception {
    //创建空PDF
    PDDocument document = new PDDocument();
    for (File image : images) {
      InputStream input = new FileInputStream(image);
      //读取图片
      BufferedImage bufferedImage = ImageIO.read(input);
      float width = bufferedImage.getWidth();
      float height = bufferedImage.getHeight();
      //创建PDF的一页
      PDPage page = new PDPage(new PDRectangle(width, height));
      document.addPage(page);
      PDImageXObject pdImageXObject = PDImageXObject.createFromFileByContent(image, document);
      PDPageContentStream contentStream = new PDPageContentStream(document, page);
      //写入图片
      contentStream.drawImage(pdImageXObject, 0, 0);
      contentStream.close();
      input.close();
    }
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    document.save(output);
    document.close();
    return output.toByteArray();
  }
}

总结

遇到问题多google

参考

Java PDF转图片
Java: Create PDF pages from images using PDFBox library
在线处理PDF工具

分类:

技术点:

相关文章: