SpringBoot 将PDF转成图片或World

时间:2022-02-18 01:03:08

SpringBoot 是一款非常流行的 Java Web 开发框架,可以用来构建各种 Web 应用程序。在本篇博客中,我们将介绍如何使用 SpringBoot 将 PDF 转换成图片或其他文件的方法。

SpringBoot 将PDF转成图片或World

准备工作

在开始之前,需要安装以下软件:

  • JDK 8或更高版本
  • Apache Maven
  • ImageMagick
  • PDFBox

Apache PDFBox

首先,我们需要引入一些必要的依赖。在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.20</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox-tools</artifactId>
    <version>2.0.20</version>
</dependency>
<dependency>
    <groupId>com.github.librepdf</groupId>
    <artifactId>openpdf</artifactId>
    <version>1.3.23</version>
</dependency>

其中,pdfbox 和 pdfbox-tools 是 Apache PDFBox 的核心依赖,用于处理 PDF 文件。openpdf 则是用于将 PDF 转换成其他格式的依赖。

接着,在 SpringBoot 应用程序中创建一个名为 PdfToImageController 的控制器。这个控制器将接受 PDF 文件,并将其转换成 PNG 格式的图像文件。

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class PdfToImageController {

  @PostMapping("/pdf-to-image")
  public ResponseEntity<Resource> pdfToImage(@RequestParam("file") MultipartFile file) throws IOException {
    // 将 MultipartFile 转换成 File
    File pdfFile = File.createTempFile("pdf", ".pdf");
    file.transferTo(pdfFile);

    // 打开 PDF 文件并获取渲染器
    PDDocument document = PDDocument.load(pdfFile);
    PDFRenderer renderer = new PDFRenderer(document);

    // 将 PDF 页面渲染成图像
    BufferedImage image = renderer.renderImageWithDPI(0, 300);

    // 将图像保存成 PNG 文件
    File pngFile = File.createTempFile("image", ".png");
    ImageIO.write(image, "png", pngFile);

    // 将 PNG 文件作为资源返回给客户端
    FileSystemResource resource = new FileSystemResource(pngFile);
    HttpHeaders headers = new HttpHeaders();
    headers.setContentType(MediaType.IMAGE_PNG);
    headers.setContentLength(resource.contentLength());
    headers.setContentDispositionFormData("attachment", pngFile.getName());
    return ResponseEntity.ok().headers(headers).body(resource);
  }
}

在上面的代码中,我们首先将 MultipartFile 对象转换成临时的 PDF 文件。然后,使用 PDFBox 库打开 PDF 文件并获取渲染器。接着,我们将第一页渲染成 PNG 格式的图像文件,并将其保存到临时文件中。最后,将 PNG 文件作为资源返回给客户端。

接下来,我们需要创建一个 HTML 表单来上传 PDF 文件并调用控制器。

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>PDF to Image Converter</title>
</head>
<body>
  <h1>PDF to Image Converter</h1>
  <form action="/pdf-to-image" method="post" enctype="multipart/form-data">
    <input type="file" name="file" accept="application/pdf">
    <button type="submit">Convert to Image</button>
  </form>
</body>
</html>

在上面的代码中,我们创建了一个简单的 HTML 表单,允许用户上传 PDF 文件并将其转换成图像。

最后,我们需要在 SpringBoot 应用程序中添加一些配置,以便允许跨域请求。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@SpringBootApplication
public class PdfToImageApplication {

  public static void main(String[] args) {
    SpringApplication.run(PdfToImageApplication.class, args);
  }

  @Bean
  public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowedMethods("*").allowedHeaders("*");
      }
    };
  }
}

在上面的代码中,我们使用 SpringBoot 的 @CrossOrigin 注解允许跨域请求。我们还定义了一个 WebMvcConfigurer bean,以便在应用程序中添加 CORS 配置。

现在我们已经完成了 SpringBoot PDF 转换成图像的示例。可以使用以下命令运行应用程序:

mvn spring-boot:run

接下来,可以访问 http://localhost:8080/index.html 打开我们的示例页面。上传 PDF 文件后,我们可以将其转换成图像并下载。

上面的示例只演示了将 PDF 转换成 PNG 图像。但是,我们还可以将 PDF 转换成其他类型的图像,如 JPEG、GIF 等。实现方式与上面的示例类似,只需要更改转换器的输出格式即可。

此外,我们还可以将 PDF 转换成其他类型的文件,如 Word 文档、HTML 等。但是,这需要使用不同的转换器和库。以下是一些可以用于将 PDF 转换成其他文件格式的库:

Apache POI:用于将 PDF 转换成 Word 文档。 Flying Saucer:用于将 PDF 转换成 HTML。 iText:一个 Java PDF 库,可以用于将 PDF 转换成其他文件格式。

使用这些库可以实现更多的文件格式转换。但是,需要注意的是,每个库都有自己的优缺点和使用方式。因此,在选择库时,需要根据实际需求和技术要求进行评估和选择。

最后,需要注意的是,将 PDF 转换成其他文件格式可能会丢失一些信息和格式,因此需要在转换之前仔细评估需求和转换效果。同时,需要根据实际情况选择适当的转换方式和工具,以便实现最佳的转换效果。

将PDF转成一张图片

首先,我们需要编写一个控制器类,用于接收PDF文件并将其转换为图片。

@RestController
public class PdfToImageController {
    
    @PostMapping("/pdf-to-image")
    public ResponseEntity<byte[]> convertToImage(@RequestParam("file") MultipartFile file) {
        try {
            PDDocument document = PDDocument.load(file.getBytes());
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            BufferedImage image = pdfRenderer.renderImage(0);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", baos);
            byte[] bytes = baos.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

在控制器类中,我们首先使用@PostMapping注解定义一个路由/pdf-to-image,用于接收PDF文件。在convertToImage方法中,我们使用PDFBox库将PDF文件加载到PDDocument对象中,然后使用PDFRenderer将PDF页面渲染为BufferedImage对象。最后,我们使用ImageIO将BufferedImage对象转换为JPEG格式的字节数组,并将其包装在一个ResponseEntity中返回给客户端。

将PDF转成多张图片

如果要将PDF转换成多张图片,则需要在控制器类中添加一个新的方法。

@RestController
public class PdfToImageController {
    
    @PostMapping("/pdf-to-image")
    public ResponseEntity<byte[]> convertToImage(@RequestParam("file") MultipartFile file) {
        try {
            PDDocument document = PDDocument.load(file.getBytes());
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            BufferedImage image = pdfRenderer.renderImage(0);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(image, "jpg", baos);
            byte[] bytes = baos.toByteArray();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.IMAGE_JPEG);
            return new ResponseEntity<>(bytes, headers, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
    
    @PostMapping("/pdf-to-images")
    public ResponseEntity<List<byte[]>> convertToImages(@RequestParam("file") MultipartFile file) {
        try {
            PDDocument document = PDDocument.load(file.getBytes());
            PDFRenderer pdfRenderer = new PDFRenderer(document);
            List<byte[]> images = new ArrayList<>();
            for (int page = 0; page < document.getNumberOfPages(); page++) {
				BufferedImage image = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				ImageIO.write(image, "jpg", baos);
				byte[] bytes = baos.toByteArray();
				images.add(bytes);	
			}
			HttpHeaders headers = new HttpHeaders();
			headers.setContentType(MediaType.IMAGE_JPEG);
			return new ResponseEntity<>(images, headers, HttpStatus.OK);
		} catch (IOException e) {
			e.printStackTrace();
			return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
		}
	}
}

convertToImages方法中,我们首先将PDF文件加载到PDDocument对象中,然后使用PDFRenderer迭代每个页面,并使用ImageIO将页面渲染为JPEG格式的字节数组。最后,我们将所有图片的字节数组存储在一个List中,并将其包装在一个ResponseEntity中返回给客户端。

将PDF转成其他文件格式

除了将PDF转换为图片外,我们还可以使用SpringBoot将PDF转换为其他文件格式。下面我们将演示如何将PDF转换为Word文档。

@RestController
public class PdfToWordController {
    
    @PostMapping("/pdf-to-word")
    public ResponseEntity<byte[]> convertToWord(@RequestParam("file") MultipartFile file) {
        try {
            PDDocument document = PDDocument.load(file.getBytes());
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Writer writer = new OutputStreamWriter(baos, StandardCharsets.UTF_8);
            PDFTextStripper stripper = new PDFTextStripper();
            stripper.setSortByPosition(true);
            stripper.setStartPage(0);
            stripper.setEndPage(document.getNumberOfPages());
            stripper.writeText(document, writer);
            writer.close();
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.setContentDispositionFormData("attachment", "output.docx");
            return new ResponseEntity<>(baos.toByteArray(), headers, HttpStatus.OK);
        } catch (IOException e) {
            e.printStackTrace();
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}

在convertToWord方法中,我们使用PDFBox库将PDF文件加载到PDDocument对象中,然后使用PDFTextStripper将PDF文本提取到一个Writer对象中。最后,我们将Writer对象中的文本转换为字节数组,并将其包装在一个ResponseEntity中返回给客户端。我们还设置了Content-Disposition头,以便将字节数组作为附件下载。

总结

在本文中,我们使用SpringBoot、PDFBox和ImageMagick演示了如何将PDF文件转换为一张或多张图片,以及将PDF转换为Word文档。这些示例演示了如何使用Java编程语言与其他开源技术集成,以实现各种文件格式之间的转换。