PDF转OFD工具类 Java~~~解决你的燃眉之急

场景说明

由于政企业务需要,文件要用到国产化的OFD,关于PDF文件转OFD文件的内容网上少之又少,要么收费要么文章内容不全,自己写了个PDF转OFD工具类,贡献给大家,若用到了点个赞就行了。话不多说,直接实操走起。

目录

1.Maven依赖

2.PDF转OFD工具类

2.1.生成OFD文件效果展示

3.可能出现的问题及解决方案

3.1.Maven配置文件settings.xml加入(能直接引入spire.pdf.free包可忽略)

3.2.jar包冲突签名问题解决方案

4.其他OFD优质文章参考 


1.Maven依赖

注意:用到了免费版spire.pdf.free-5.1.0.jar,收费版会有水印的。

限制:带有图片pdf可以转前3页,纯文本pdf可以转前10页。

解决:具体解决限制页数问题,工具类中有具体思路。

<repositories>
     <repository>
         <id>com.e-iceblue</id>
          <name>e-iceblue</name>
          <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
     </repository>
</repositories>




 <dependencies>

 <!--    pdf 转 ofd ,这个引入免费包需要Maven配置文件-->
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.pdf.free</artifactId>
            <version>5.1.0</version>
        </dependency>


        <dependency>
            <groupId>org.ofdrw</groupId>
            <artifactId>ofdrw-full</artifactId>
            <version>2.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.ofdrw</groupId>
            <artifactId>ofdrw-tool</artifactId>
            <version>2.3.1</version>
        </dependency>


        <!--ofd合并签名-->
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.70</version> 
        </dependency>
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcpkix-jdk15on</artifactId>
            <version>1.70</version>
        </dependency>
        
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.29</version> <!-- 请根据需要调整版本号 -->
        </dependency>

</dependencies>

2.PDF转OFD工具类

package com.jsite.modules.flow.util;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.ofdrw.tool.merge.OFDMerger;
import org.springframework.util.StringUtils;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;


/**
 * PDF文件转OFD文件工具类
 *
 * @author
 * @date 2024/3/29 15:27
 * @describe
 */
public class PDFToOFDUtil {


    /**
     * 测试方法
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {

        // 记录程序开始时间(以纳秒为单位)
        long startTime = System.nanoTime();
        
        
        //1.源pfd文件
        String inputFilePath = "D:\\data\\PDF\\12222\\202445045.pdf";
        
        //2.源pfd文件分隔成按页文件合集
        List<String> listPfd = splitPDFByPageCount(inputFilePath, 3);
        
        //3.PDF文件合集转换为OFD文件合集
        List<String> listOfd = new ArrayList<>();
        for (String s : listPfd) {
            String replace = s.replace("pdf", "ofd");
            //用的冰蓝免费的jar包,pdf每次转换带图片可转前3页,纯文本可转前10页,所以我们每次转换按照情况实现最大化就行。
            transPdfToOfd(s, replace);
            listOfd.add(replace);
        }
        
        //4.OFD文件合集合并一个完整版ofd文件(最终实现源pfd转ofd)
        String outputFilePathOfd = inputFilePath.replace("pdf", "ofd");
        mergeOfdFiles(listOfd, outputFilePathOfd);
        System.out.println("完整版ofd文件路径:" + outputFilePathOfd);
        
        //5.删除多余文件
        listPfd.addAll(listOfd);
        for (String relFilePath : listPfd) {
            Files.deleteIfExists(Paths.get(relFilePath));
        }
        
        
        
        long endTime = System.nanoTime();
        double durationInSeconds = (endTime - startTime) / 1_000_000_000.0;
        // 输出运行时间
        System.out.println("程序运行时间: " + durationInSeconds + " 秒");

    }


    /**
     * @Description pdf文档 转 ofd文档
     * @date 2024/3/29 15:27
     * @Param pdfPath pdf文件全路径
     * @Param ofdPath ofd 输出全路径
     **/
    public static void transPdfToOfd(String pdfPath, String ofdPath) {
        if (StringUtils.isEmpty(ofdPath) || StringUtils.isEmpty(pdfPath)) {
            throw new RuntimeException("pdf或ofd文档地址不能为空");
        }

        byte[] bytes = getBytesFromFile(new File(pdfPath));
        transPdfToOfd(bytes, ofdPath);
    }

    /**
     * @Description pdf byte数组转ofd文档输出
     * @date 2024/3/29 15:27
     * @Param pdfBytes 字节数组
     * @Param ofdPath ofd文档输出全路径
     **/
    public static void transPdfToOfd(byte[] pdfBytes, String ofdPath) {
        if (pdfBytes == null || pdfBytes.length <= 0) {

            throw new RuntimeException("pdf转ofd转化失败,pdf文件错误,pdf文件内容不能为空");
        }

        if (StringUtils.isEmpty(ofdPath)) {
            throw new RuntimeException("ofd文档输出地址不能为空");
        }

        long startTime = LocalDateTime.now().atOffset(ZoneOffset.of("+8")).toInstant().toEpochMilli();
        //构建PDF内容
        PdfDocument pdf = new PdfDocument();
        pdf.loadFromBytes(pdfBytes);

        pdf.saveToFile(ofdPath, FileFormat.OFD);

        long endTime = LocalDateTime.now().atOffset(ZoneOffset.of("+8")).toInstant().toEpochMilli();
    }

    /**
     * @return byte[]
     * @Description 把一个文件转化为byte字节数组
     * @date 2024/3/29 15:27
     * @Param file 文件
     **/
    public static byte[] getBytesFromFile(File file) {
        byte[] data;
        try (InputStream inputStream = Files.newInputStream(file.toPath());
             BufferedInputStream bis = new BufferedInputStream(inputStream);
             ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            int len;
            byte[] buffer = new byte[1024];
            while ((len = bis.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }

            data = bos.toByteArray();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        return data;
    }


    /**
     * 使用iTextPDF合并PDF文件
     *
     * @param pdfFiles  要合并的PDF文件路径
     * @param mergedPdf 合并后的PDF文件路径
     * @throws IOException
     * @throws DocumentException
     */
    public static void mergePdfFiles(List<String> pdfFiles, String mergedPdf) throws IOException, DocumentException {
        Document document = new Document();
        PdfCopy copy = new PdfCopy(document, new FileOutputStream(mergedPdf));
        document.open();
        PdfReader reader;
        for (String file : pdfFiles) {
            reader = new PdfReader(file);
            int n = reader.getNumberOfPages();
            for (int page = 0; page < n; ) {
                copy.addPage(copy.getImportedPage(reader, ++page));
            }
            copy.freeReader(reader);
            reader.close();
        }
        document.close();
    }


    /**
     * OFD合并
     *
     * @param ofdFiles
     * @param mergeOfd
     * @throws IOException
     * @throws DocumentException
     */
    public static void mergeOfdFiles(List<String> ofdFiles, String mergeOfd) {
        // 1. 提供合并文件输出位置。
        Path dst = Paths.get(mergeOfd);
        // 3. 创建合并对象
        try (OFDMerger ofdMerger = new OFDMerger(dst)) {
            for (String ofdFile : ofdFiles) {
                Path d1Path = Paths.get(ofdFile);
                // 4. 添加合并文档和页面。
                ofdMerger.add(d1Path);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 将 PDF 文件按指定页数分隔,并保存到与输入文件同级的输出目录中。
     *
     * @param inputFilePath 输入 PDF 文件的路径
     * @param pagesPerFile  每个 PDF 文件包含的页数比如3页为一个文件
     * @return 分隔后的 PDF 文件路径列表
     */
    public static List<String> splitPDFByPageCount(String inputFilePath, int pagesPerFile) {
        // PDF 文件路径列表
        List<String> listPdf = new ArrayList<>();
        try {
            // 加载 PDF 文件
            File inputFile = new File(inputFilePath);
            PDDocument document = PDDocument.load(inputFile);

            // 获取输入文件的父目录
            String outputDirPath = inputFile.getParent();

            // 创建输出目录
            File outputDir = new File(outputDirPath);
            if (!outputDir.exists()) {
                outputDir.mkdirs();
            }

            // 获取总页数
            int totalPages = document.getNumberOfPages();

            // 计算文件数量
            int numFiles = (int) Math.ceil((double) totalPages / pagesPerFile);

            // 遍历每个文件
            for (int fileIndex = 0; fileIndex < numFiles; fileIndex++) {
                PDDocument singleFileDoc = new PDDocument();

                // 计算每个文件的起始页和结束页
                int startPage = fileIndex * pagesPerFile;
                int endPage = Math.min(startPage + pagesPerFile, totalPages);

                // 添加页到当前文档
                for (int pageIndex = startPage; pageIndex < endPage; pageIndex++) {
                    PDPage page = document.getPage(pageIndex);
                    singleFileDoc.addPage(page);
                }

                // 保存分隔出的 PDF 文件
                String outputFileName = outputDirPath + "/output-part-" + (fileIndex + 1) + ".pdf";
                singleFileDoc.save(outputFileName);
                singleFileDoc.close();
                listPdf.add(outputFileName);
            }

            // 关闭原始文档
            document.close();

            System.out.println("PDF 按页数分隔完成,文件已保存到:" + outputDirPath);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return listPdf;
    }


}

2.1.生成OFD文件效果展示

3.可能出现的问题及解决方案

3.1.Maven配置文件settings.xml加入(能直接引入spire.pdf.free包可忽略)
    <mirror>
    <id>aliyunmaven</id>
    <!-- *是不能下载com.e-iceblue的依赖的,需要加入!com.e-iceblue -->
    <mirrorOf>*,!com.e-iceblue</mirrorOf>
    <name>阿里云公共仓库</name>
    <url>https://maven.aliyun.com/repository/public</url>
    </mirror>

3.2.jar包冲突签名问题解决方案

bcpkix-jdk15on 与 bcpkix-jdk14 ,文件签名时引用冲突了,排除 bcpkix-jdk14引用。

        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
            <exclusions>
                <exclusion>
                    <groupId>org.bouncycastle</groupId>
                    <artifactId>bcprov-jdk14</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>bouncycastle</groupId>
                    <artifactId>bcprov-jdk14</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

4.其他OFD优质文章参考 

4.1.启发文章:

java实现pdf转ofd,“Evaluation Warning : The do cument was created with Spire.PDF for j ava”这个东西就很烦_evaluation warning : the document was created with-CSDN博客

 4.2.这个更多有关OFD操作免费开源的文章​​​【推荐】

GitHub - ofdrw/ofdrw: OFD Reader & Writer 开源的OFD处理库,支持文档生成、数字签名、文档保护、文档合并、转换、导出等功能,文档格式遵循《GB/T 33190-2016 电子文件存储与交换格式版式文档》。

4.3.有关OFD文件前端预览,业务没要求没实现,哈哈。其他思路是转图片或者PDF预览。

PDF转图片 JAVA-CSDN博客

  • 14
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值