java PDF合并,并且插入指定标签

<dependency>
    <groupId>com.lowagie</groupId>
    <artifactId>itext</artifactId>
    <version>2.1.7</version>
</dependency>
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.24</version>
</dependency>
<!-- iText -->
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.1.15</version>
    <type>pom</type>
</dependency>
package org.jeecg.modules.manage.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.destination.PDPageFitDestination;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDDocumentOutline;
import org.apache.pdfbox.pdmodel.interactive.documentnavigation.outline.PDOutlineItem;
import org.jeecg.common.api.vo.Result;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class PdfMergeAtPosition {
    /**
     * 合并PDF文件并添加新的标签
     * @param pdfMergedFile 需要插入的PDF文件
     * @param pdfOriginalFile 原来PDF文件
     * @param newLabel 新的标签名称
     * @param insertLabel 要插入标签的位置(插入到该标签之前)
     * @param fileName 合并后的文件名
     * @return
     */
    public static Result<?> pdfMergeAtPosition(File pdfMergedFile, File pdfOriginalFile ,
                                               String newLabel , String insertLabel
            , String fileName){
        try{
            // 打开两个PDF文档
            PDDocument mergedDocument = PDDocument.load(pdfMergedFile);
            PDDocument originaDocument = PDDocument.load(pdfOriginalFile);
            // 记录目的标签的页码
            int insertPosition = 0;
            // 创建一个新的文档,合并两个文档的页面
            PDDocument document = new PDDocument();
            // 获取新书签结构
            PDDocumentOutline documentOutline = new PDDocumentOutline();
            document.getDocumentCatalog().setDocumentOutline(documentOutline);
            // 获取目标书签结构
            PDDocumentOutline outline = originaDocument.getDocumentCatalog().getDocumentOutline();
            // 存储书签
            Map<PDPage, String> pageBookmarkMap = new HashMap<>();
            // 获取所有书签
            PDOutlineItem item = outline.getFirstChild();
            while (item != null) {
                PDPage page = item.findDestinationPage(originaDocument);
                if (page != null) {
                    pageBookmarkMap.put(page, item.getTitle());
                    if(insertLabel.equals(item.getTitle())){
                        insertPosition = originaDocument.getPages().indexOf(item.findDestinationPage(originaDocument));
                    }
                }

                item = item.getNextSibling();
            }
            // 保存当前书签名称
            String currentBookmarkName = "";
            int pageIndex = 0;
            // 获取B.pdf的页面
            PDPageTree pagesB = originaDocument.getPages();
            for (PDPage pageB : pagesB) {
                if (pageIndex++ == insertPosition) {
                    break;
                }
                document.addPage(pageB);
                if (pageBookmarkMap.get(pageB) != null &&!pageBookmarkMap.get(pageB).equals(currentBookmarkName)) {
                    currentBookmarkName = pageBookmarkMap.get(pageB);
                    // 创建书签
                    PDOutlineItem bookmark = new PDOutlineItem();
                    bookmark.setTitle(pageBookmarkMap.get(pageB));
                    documentOutline.addLast(bookmark);
                    // 设置书签的位置
                    PDPageFitDestination destination = new PDPageFitDestination();
                    destination.setPage(pageB);
                    bookmark.setDestination(destination);
                }
            }
            // 其次,添加A.pdf的所有页面到新文档
            for(int i = 0 ; i < mergedDocument.getPages().getCount(); i++){
                document.addPage( mergedDocument.getPages().get(i));
                if(i == 0 ){
                    // 创建书签
                    PDOutlineItem bookmark = new PDOutlineItem();
                    bookmark.setTitle(newLabel);
                    documentOutline.addLast(bookmark);
                    // 设置书签的位置
                    PDPageFitDestination destination = new PDPageFitDestination();
                    destination.setPage(mergedDocument.getPages().get(i));
                    bookmark.setDestination(destination);
                }

            }
            // 最后,添加B.pdf中剩下的页面到新文档
            for(int i = 0 ;i < originaDocument.getPages().getCount(); i++){
                if(i >= insertPosition){
                    PDPage pdPage = originaDocument.getPages().get(i);
                    document.addPage(pdPage);
                    if (pageBookmarkMap.get(pdPage) != null &&!pageBookmarkMap.get(pdPage).equals(currentBookmarkName)) {
                        // 创建书签
                        PDOutlineItem bookmark = new PDOutlineItem();
                        bookmark.setTitle(pageBookmarkMap.get(pdPage));
                        documentOutline.addLast(bookmark);
                        // 设置书签的位置
                        PDPageFitDestination destination = new PDPageFitDestination();
                        destination.setPage(pdPage);
                        bookmark.setDestination(destination);
                    }
                }
            }
            // 获取保存文件的路径
            if(!new File("path/../..").exists()){
                new File("path/../..").mkdir();
            }
            String savePath = FilePath.HeadPath+FilePath.Merge+"/"+fileName;
            // 保存合并后的文档
            document.save(savePath);
            // 关闭文档
            mergedDocument.close();
            originaDocument.close();
            document.close();
        } catch (Exception e){
            log.error(pdfOriginalFile.getName() + "合并失败!", e);
            return Result.error("合并失败!");
        }
        return Result.ok("合并成功!");
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值