likes
comments
collection
share

【奇思妙想】送老婆一个PDF切图小工具

作者站长头像
站长
· 阅读数 4

老婆需要一个PDF工具,咱能说做不出来?

最近老婆需要将PDF文件分页切割并转成图片,但使用在线工具时经常遇到繁琐的广告。她问我能否做一个工具来简化这个过程。作为程序员,咱程序员能说不会做吗?当然不能,于是便有了我摸鱼写的一个小工具,【PDF切图】,将源码分享给大家。

【PDF切图】源码分享 跟着我一步一步来

1、首先我们需要一个SpringBoot项目

可以参考我的文章

2、添加Maven依赖

在父Pom.xml文件中添加

        <pdfbox.version>2.0.9</pdfbox.version>    

            <dependency>
                <groupId>org.apache.pdfbox</groupId>
                <artifactId>pdfbox</artifactId>
                <version>${pdfbox.version}</version>
            </dependency>

pom.xml中添加

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

3、封装我们的工具类(非常好用,直接分享给你们)

文件工具类FileUtils

package com.le.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileUtils {


    /**
     * 获取不带扩展名的文件名
     * @param fileName
     * @return
     */
    public static String getFileNameRemoveSuffix(String fileName) {
        int pos = fileName.lastIndexOf(".");
        if (pos > 0) {
            return fileName.substring(0, pos);
        }
        return fileName;
    }

    /**
     * 递归删除指定目录及其内容。
     *
     * @param directory 要删除的目录
     */
    public static void deleteDirectory(File directory) {
        File[] allContents = directory.listFiles();
        if (allContents != null) {
            for (File file : allContents) {
                deleteDirectory(file);
            }
        }
        directory.delete();
    }

    /**
     * 将指定目录中的图像压缩为zip文件,并将其写入输出流中。
     *
     * @param directory     包含图像文件的目录
     * @param outputStream  要写入zip文件的输出流
     * @throws IOException 如果发生I/O错误
     */
    public static void zipImages(File directory, OutputStream outputStream) throws IOException {
        try (ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
            File[] imageFiles = directory.listFiles();
            if (imageFiles != null) {
                for (File imageFile : imageFiles) {
                    ZipEntry zipEntry = new ZipEntry(imageFile.getName());
                    zipOut.putNextEntry(zipEntry);
                    try (FileInputStream fis = new FileInputStream(imageFile)) {
                        byte[] bytes = new byte[1024];
                        int length;
                        while ((length = fis.read(bytes)) >= 0) {
                            zipOut.write(bytes, 0, length);
                        }
                    }
                }
            }
        }
    }

    /**
     * 创建临时文件
     * @return
     * @throws IOException
     */
    public static File createTempDirectory() throws IOException {
        File tempDir = File.createTempFile("temp", Long.toString(System.nanoTime()));
        if (!tempDir.delete() || !tempDir.mkdir()) {
            throw new IOException("Could not create temp directory: " + tempDir);
        }
        return tempDir;
    }
}

PDF工具类PdfUtils

package com.le.common.utils;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.List;

import org.apache.pdfbox.multipdf.Splitter;

public class PdfUtils {

    /**
     * 将PDF文件拆分为单独的图像,并将它们保存在指定的目录中。
     * PDF的每一页被转换为一个单独的图像文件。
     *
     * @param inputPdfFile       要拆分的输入PDF文件
     * @param outputImageDirectory 图像文件将要保存的目录
     * @throws IOException 如果发生I/O错误
     */
    public static void splitPdfToImages(File inputPdfFile, File outputImageDirectory) throws IOException {
        try (PDDocument document = PDDocument.load(inputPdfFile)) {
            Splitter splitter = new Splitter();
            List<PDDocument> pages = splitter.split(document);
            int pageIndex = 1;
            for (PDDocument page : pages) {
                PDFRenderer renderer = new PDFRenderer(page);
                BufferedImage image = renderer.renderImageWithDPI(0, 300, ImageType.RGB);
                // 写入图像文件
                File outputImage = new File(outputImageDirectory, "page" + pageIndex + ".png");
                ImageIO.write(image, "png", outputImage);
                pageIndex++;
                page.close();
            }
        }
    }

}

4、接口:PDF文件切割成图片输出

package com.le.admin.after.api.mytools;

import com.le.common.utils.FileUtils;
import com.le.common.utils.PdfUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

@RestController
@RequestMapping("/tools/pdf")
public class PdfToolController {

    /**
     * pdf文件切割成图片输出
     * @param pdfFile
     * @return
     */
    @PostMapping("/pdfCutToImage")
    public ResponseEntity<byte[]> processPdf(@RequestParam("pdfFile") MultipartFile pdfFile) {
        try {
            File tempDir = FileUtils.createTempDirectory();
            File pdfInputFile = new File(tempDir, pdfFile.getOriginalFilename());
            pdfFile.transferTo(pdfInputFile);

            // 将PDF文件拆分为单独的图像
            PdfUtils.splitPdfToImages(pdfInputFile, tempDir);

            // 将图像压缩为zip文件
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            FileUtils.zipImages(tempDir, baos);

            // 删除临时目录及其内容
            FileUtils.deleteDirectory(tempDir);

            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "attachment; filename=images.zip");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.parseMediaType("application/zip"))
                    .body(baos.toByteArray());
        } catch (IOException e) {
            e.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
        }
    }
}

东西做出来了,老婆很满意

OK,我们就大功告成了!

总结

一定要多思考,如果人永远待在舒适圈的话,人永远不会成长。共勉

觉得作者写的不错的,值得你们借鉴的话,就请点一个免费的赞吧!这个对我来说真的很重要。૮(˶ᵔ ᵕ ᵔ˶)ა