pdf内容三张以上转图片,使用spire.pdf.free

一、依赖

   <spire.pdf.free.version>9.13.0</spire.pdf.free.version>
        <itextpdf.version>5.5.13</itextpdf.version>
   <dependency>
                <groupId>e-iceblue</groupId>
                <artifactId>spire.pdf.free</artifactId>
                <version>${spire.pdf.free.version}</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>${itextpdf.version}</version>
            </dependency>

二、思路:

①问题:

1、spire.pdf.free只能免费转换每个PDF的前三页

2、转换速度慢

3、多线程合并后页数顺序问题

②解决

1、将PDF文档根据页数截断为多个PDF,每个PDF最多三页

2、使用线程池多线程异步处理

3、map里的索引

三、代码:

1、 转换的类

package com.shiqiao.nev.business.infra.adapter.pdftoPic;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.graphics.PdfImageType;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

public class PdfToPicConverter {

    private final byte[] pdfFileByteStream;
    private final Integer pageCount;
    private List<InputStream> picResult;


    public PdfToPicConverter(InputStream pdfFile) {
        try {
            pdfFileByteStream = inputStreamToByteArray(pdfFile);
        } catch (Exception e) {
            throw new RuntimeException("pdf文件转换为字节流失败", e);
        }
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromStream(new ByteArrayInputStream(pdfFileByteStream));
        pageCount = pdf.getPages().getCount();
   
    }

    public PdfToPicConverter(byte[] pdfFile) {
        pdfFileByteStream = pdfFile;
      PdfDocument pdf = new PdfDocument();
        pdf.loadFromStream(new ByteArrayInputStream(pdfFileByteStream));
        pageCount = pdf.getPages().getCount();
   
    }

    public List<InputStream> convertToPictures(ExecutorService executorService) {

        picResult = new ArrayList<>();

        // 每三页为一组
        int groupSize = 3;
        int numGroups = (pageCount + groupSize - 1) / groupSize;

        List<Future<List<InputStream>>> futures = new ArrayList<>();
        for (int i = 0; i < numGroups; i++) {
            int startPage = i * groupSize;
            int endPage = Math.min(startPage + groupSize, pageCount);
            if (executorService != null) {
                futures.add(executorService.submit(() -> convertGroup(startPage, endPage)));
            }

        }

        // 等待所有任务完成并合并结果
        for (Future<List<InputStream>> future : futures) {
            try {
                picResult.addAll(future.get());
            } catch (Exception e) {
                throw new RuntimeException("图片转换失败", e);
            }
        }

        return picResult;
    }

    private InputStream splitPDFFile(byte[] pdfFileByteStream, int from, int end) {
        Document document = null;
        PdfCopy copy = null;

        try (ByteArrayInputStream bais = new ByteArrayInputStream(pdfFileByteStream);
             ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

            PdfReader reader = new PdfReader(bais);
            int n = reader.getNumberOfPages();
            if (end == 0 || end > n) {
                end = n;
            }
            document = new Document(reader.getPageSize(1));
            copy = new PdfCopy(document, baos);
            document.open();
            for (int j = from + 1; j <= end; j++) {  // 注意这里j从from+1开始
                document.newPage();
                PdfImportedPage page = copy.getImportedPage(reader, j);
                copy.addPage(page);
            }
            document.close();
            return new ByteArrayInputStream(baos.toByteArray());
        } catch (IOException | DocumentException e) {
            throw new RuntimeException("PDF文件拆分失败", e);
        }
    }


    private List<InputStream> convertGroup(int startPage, int endPage) {
        InputStream inputStream = splitPDFFile(pdfFileByteStream, startPage, endPage);
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromStream(inputStream);
        int end = endPage - startPage;
        List<InputStream> groupResult = new ArrayList<>();
        for (int i = 0; i < end; i++) {
            BufferedImage image = pdf.saveAsImage(i, PdfImageType.Bitmap, 500, 500);
            try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
                ImageIO.write(image, "PNG", baos);
                groupResult.add(new ByteArrayInputStream(baos.toByteArray()));
            } catch (IOException e) {
                throw new RuntimeException("图片保存失败", e);
            }
        }
        pdf.close();
        return groupResult;

        return new ArrayList<>();
    }

    protected byte[] inputStreamToByteArray(InputStream inputStream) throws IOException {
        int bufferSize = 4096;
        byte[] buffer = new byte[bufferSize];
        int bytesRead;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        while ((bytesRead = inputStream.read(buffer)) != -1) {
            baos.write(buffer, 0, bytesRead);
        }

        return baos.toByteArray();
    }
}

2、使用的地方

  public List<FileDTO> pdfToPng(byte[] filebyte, String fileName) {
        List<FileDTO> fileDTOS = new ArrayList<>();
        PdfToPicConverter pdfToPicConverter = new PdfToPicConverter(filebyte);
        List<InputStream> inputStreams = pdfToPicConverter.convertToPictures(pdfCovertPicExectorPool);

        inputStreams.forEach((e) -> {
            // 生成文件名
            String pgnNames = "fileName"+inputStreams.indexOf(e) + ".png";
            FileDTO fileDTO = new FileDTO(e, pgnNames);
            fileDTOS.add(fileDTO);
        });
        return fileDTOS;
    }

四、spire.pdf.free 的下载:maven仓库里进去然后点官网就能下jar包了

Free Spire.PDF for .NET 是 Spire.PDF for .NET 的免费版本,无需购买即可用于个人或商业用途。使用该组件,程序员可以 在.NET 程序中创建、读取、写入、编辑和操作 PDF 文档。这个控件能支持的功能十分全面,例如文档安全性设置(电子签名),提取 PDF 文本、附件、图片PDF 合并和拆分,更新 Metadata,设置 Section,绘制图形、插入图片、表格制作和加工、导入数据等等。除此以外,Spire.PDF 还可以将 TXT 文本、图片、HTML 高质量地换为 PDF 文件格式。 主要功能如下: 1.高质量的文档换。Free Spire.PDF for .NET 支持 PDF 到 Word、XPS、SVG、EMF、Text 和图片(EMF、JPG、PNG、BMP、TIFF)的格式换。也支持从 XML、HTML、RTF、XPS、Text、图片等格式生成 PDF 文档。 2.文档操作及域功能。支持合并、拆分 PDF 文档,在原有的 PDF 文档页添加覆盖页。同时,Spire.PDF 提供导入、邮戳、小册子功能,以及帮助用户从数据库读取数据并填充到域的域填写功能。 3. 安全性设置。用户可以通过设置密码和数字签名来保护 PDF 文档。用户密码和所有者密码可以确定加密的 PDF 文档的可读性、可修改性、是否可打印等有选择性的限制。与此同时,数字签名作为一个更有效的方法,可以应用于维护和对PDF文档进行身份验证。 4.数据提取。支持快速高效地从 PDF 文档提取图片、文本、PDF 分页,以及附件。 5.文件属性设置。支持对 Metadata、文件属性、页面方向、页面大小进行设置。其中文件属性包括文件限制(打印、页面提取、加评论等方面的权限限制)以及文件描述属性(文件名称、作者、主题、关键字等)。使用 Spire.PDF for .NET,用户还可以根据自己阅读喜好设定默认打开页码,分页模式,缩放比例和打印缩放,等等。 6.其他功能。 支持多种语言,支持字体格式、对齐方式设置。 绘制文字,图片,图形。 支持添加图层,透明图像,Color Space,条形码到 PDF。 支持 PDF/A-1b、PDF/x1a:2001 格式。 添加梯状图形和矢量图像到指定位置。 添加并格式化表格。 插入交互元素,例如添加自定义的 Annotation、Action、JavaScript、附件、书签等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值