java使用itext7依赖实现多种类型文档合并

需求描述:

1.创建一个文档,将查询到的子父级数据写入文档中

2.中途可能存在img,pdf,doc,docx,excel类型的文档,需要依次插入到文档中作为内容

  1. 引入依赖
 <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext7-core</artifactId>
            <version>7.1.15</version>
            <type>pom</type>
        </dependency>

2.开始实现

     public boolean savePdf(String taskId, String taskName) {
//获取数据 数据类型为子父级结构
        ClauseAction clauseAction = new ClauseAction();
        clauseAction.setTaskId(taskId);
        List<Map<String, Object>> list = responsibilityAuditReadService.queryAuditTasks(clauseAction);

   if (ValidateUtil.isEmpty(list)) {
            return false;
        }
        String filepath = "";
        String datePath = "";
        String fileNameUuid = UUIDUtils.getUUID();


    datePath = com.yinhai.djps.utils.DateUtils.dateToString(new Date(), "yyyyMMdd");
            String path = taskFilePath + File.separator + datePath;
            filepath = path + File.separator + fileNameUuid + ".pdf";
            File fileDirectory = new File(path);
            //判断文件夹是否存在不存在则新增
            if (!fileDirectory.exists() && fileDirectory.mkdirs()) {
                log.debug("创建文件夹成功");
            }


        //根据任务id获取所有佐证材料 按条款id分组
        Map<String, List<Map<String, Object>>> fileMap = responsibilityAuditReadService.queryFileByTaskIdGroupByDept(taskId);

        List<String> imgTypeList = Arrays.asList("png", "jpg", "jpeg", "bmp", "gif");


    try {
            // 创建一个PdfWriter实例,将Document对象写入指定的文件路径
            PdfWriter writer = new PdfWriter(filepath);
            // 创建PdfDocument实例,与PdfWriter关联
            PdfDocument pdfDoc = new PdfDocument(writer);

            // 创建Document实例,指定页面大小和PdfDocument
            // 注意:在iText 7中,应该使用PageSize.A4.getRectangle()来获取页面尺寸的Rectangle对象
            Document document = new Document(pdfDoc);

            // 设置中文字体
            // 设置字体提供者,确保支持特殊字符
            // 确定字体已安装在系统上,并且知道其名称和路径
            PdfFont font = PdfFontFactory.createFont(getFilePath(), PdfEncodings.IDENTITY_H, true);
            for (Map<String, Object> map : list) {
                //开始写文件内容
                getDocument(fileMap, imgTypeList, pdfDoc, document, font, map);
            }
            document.close();

     
               //保存文件信息到本地
                ThirdWorkTaskFile fileEntity = new ThirdWorkTaskFile();
                fileEntity.setTaskId(taskId);
                fileEntity.setFileName(taskName + ".pdf");
                fileEntity.setFileStyle("pdf");
                fileEntity.setDcsFileId("");
                fileEntity.setFilePath(IConstants.PATH_SEPARATOR + IConstants.FILE_PATH + IConstants.PATH_SEPARATOR + datePath + IConstants.PATH_SEPARATOR + fileNameUuid + ".pdf");
                thirdWorkTaskFileWriteService.saveFile(fileEntity);


        } catch (IOException e) {
            log.error("生成文件失败", e);
            return false;
        }

        return true;
}


    private void getDocument(Map<String, List<Map<String, Object>>> fileMap, List<String> imgTypeList, PdfDocument pdfDoc, Document document, PdfFont font, Map<String, Object> map) {

        document.add(
                new Paragraph(
                        new Text(
                                getObjectString(map.get("provisionNo")
                                        + getObjectString(map.get("provisionName")))
                                        + "   [自评分]: "
                                        + getSelfRatingAndProvisionSum(map))
                ).setFont(font));
        if (map.get(CHILDREN) instanceof ArrayList) {
            for (Object obj : (List<?>) map.get(CHILDREN)) {
                writeByProvision(fileMap, imgTypeList, pdfDoc, document, font, obj);
            }
        } else if (map.get(CHILDREN) != null) {
            Object obj = map.get(CHILDREN);
            writeByProvision(fileMap, imgTypeList, pdfDoc, document, font, obj);
        }
    }



    private void writeByProvision(Map<String, List<Map<String, Object>>> fileMap, List<String> imgTypeList, PdfDocument pdfDoc, Document document, PdfFont font, Object obj) {
        if (obj == null) {
            return;
        }
        HashMap childMap;
        try {
            childMap = JSON.parseObject(JSON.toJSONString(obj), HashMap.class);
        } catch (Exception e) {
            log.error("Obj转map 失败 ", e);
            return;
        }

        if (childMap == null) {
            return;
        }
        //条款名称
        document.add(new Paragraph(new Text(getObjectString(childMap.get("provisionName")))).setFont(font));
        //责任科室
        document.add(
                new Paragraph(
                        new Text("[责任(牵头)科室]:"
                                + getObjectString(childMap.get("secondaryDeptName"))
                                + " ; [总分]:"
                                + objectToString(childMap.get(PROVISION_SCORE))
                                + " ; [目标分]:"
                                + objectToString(childMap.get("targetRating"))
                                + " ; [自评分]:"
                                + objectToString(childMap.get(SELF_RATING))

                        )).setFont(font)
        );
        document.add(new Paragraph(new Text("[自评结论]:" + getObjectString(childMap.get("conclusion")))).setFont(font));
//        按承办科室拼接材料
        List<Map<String, Object>> fileList = fileMap.get(getObjectString(childMap.get("provisionId")));
        if (ValidateUtil.isEmpty(fileList)) {
            return;
        }
        log.info("材料list长度:{}", fileList.size());
        List<Map<String, Object>> filterList = fileList.stream().filter(item -> ValidateUtil.isNotEmpty(getObjectString(item.get("undertakeId")))).collect(toList());
        if (ValidateUtil.isEmpty(filterList)) {
            return;
        }
        Map<String, List<Map<String, Object>>> fileGroupByDept = filterList.stream()
                .collect(Collectors.groupingBy(item -> getObjectString(item.get("undertakeId"))));
        if (ValidateUtil.isEmpty(fileGroupByDept)) {
            return;
        }
        //遍历承办科室
        for (Map.Entry<String, List<Map<String, Object>>> entrySet : fileGroupByDept.entrySet()) {
            List<Map<String, Object>> deptFileList = fileGroupByDept.get(entrySet.getKey());
            if (ValidateUtil.isEmpty(deptFileList)) {
                continue;
            }
            document.add(new Paragraph(new Text("[承办科室]:" + getObjectString(deptFileList.get(0).get("undertakeName")) + ", 佐证材料:")).setFont(font));
            List<Map<String, Object>> imgList = deptFileList.stream().filter(file -> imgTypeList.contains(getObjectString(file.get(FILE_STYLE)))).collect(toList());

            if (ValidateUtil.isNotEmpty(imgList)) {
                addImg(document, font, imgList);
            }
            List<Map<String, Object>> addFileList = deptFileList.stream().filter(file -> !imgTypeList.contains(getObjectString(file.get(FILE_STYLE)))).collect(toList());

            if (ValidateUtil.isNotEmpty(addFileList)) {
                //向文档写入文件类型内容
                addFile(pdfDoc, document, addFileList);
                //分页
                document.add(new AreaBreak(AreaBreakType.NEXT_AREA));
            }

        }

    }



    private void addFile(PdfDocument pdfDoc, Document document, List<Map<String, Object>> addFileList) {
        log.info("文件数量:{}", addFileList.size());
        for (Map<String, Object> addFile : addFileList) {
            String fileRealPath = taskFilePath + File.separator + getObjectString(addFile.get(FILE_PATH)).replace("/file/", "").replace("/", File.separator);
            if ("pdf".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE)))) { //拼接pdf
                log.info("================开始拼接pdf文档,文件id:{}=========", addFile.get("id"));
                // 检查文件是否存在
                if (!new File(fileRealPath).exists()) {
                    log.info("文件找不到:{}", fileRealPath);
                } else {
                    //将pdf复制到已创建文档中
                    pdfCopyToDocument(pdfDoc, document, fileRealPath);
                }
            } else {//转成pdf再拼接
                if ("doc".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE))) || "docx".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE)))) {
                    addWord(pdfDoc, document, addFile, fileRealPath);
                } else if ("xlsx".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE)))
                        || "xls".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE)))
                        || "csv".equalsIgnoreCase(getObjectString(addFile.get(FILE_STYLE)))
                ) {
                    addExcel(pdfDoc, document, addFile, fileRealPath);

                }
            }
        }
    }


    private void addExcel(PdfDocument pdfDoc, Document document, Map<String, Object> addFile, String fileRealPath) {
        try {
            log.info("================开始拼接excel文档,文件id:{}=========", addFile.get("id"));
            FileInputStream fis;
            File resultFile = new AsyncMethodUtil().getTempFile(getObjectString(addFile.get(FILE_NAME)), IConstants.FILE_FORMAT_PDF);
            String tempFilePath;
            tempFilePath = resultFile.getCanonicalPath();
            new AsposeUtil().excel2Pdf(fileRealPath, tempFilePath);
            fis = new FileInputStream(new File(tempFilePath));
            // 将FileInputStream的内容读入到字节数组中
            byte[] buffer;
            buffer = new byte[fis.available()];
            int read;
            read = fis.read(buffer);
            log.info("写出{}字节", read);
            fis.close();
            //将pdf复制到已创建文档中
            if (read != 0) {
                pdfCopyToDocument(pdfDoc, document, tempFilePath);
            }
        } catch (Exception e) {
            log.info("Excel文件地址{}文件名称{}t_djps_material_task_file表id{}", addFile.get(FILE_PATH), addFile.get(FILE_NAME), addFile.get("id"));
            log.error("Excel文件找不到", e);
        }
    }

    private void addWord(PdfDocument pdfDoc, Document document, Map<String, Object> addFile, String fileRealPath) {
        try {
            log.info("================开始拼接word文档,文件id:{}=========", addFile.get("id"));
            FileInputStream fis;
            File resultFile = new AsyncMethodUtil().getTempFile(getObjectString(addFile.get(FILE_NAME)), IConstants.FILE_FORMAT_PDF);
            String tempFilePath;
            tempFilePath = resultFile.getCanonicalPath();
            new AsposeUtil().word2Pdf2(fileRealPath, tempFilePath);
            fis = new FileInputStream(new File(tempFilePath));
            // 将FileInputStream的内容读入到字节数组中
            byte[] buffer;
            buffer = new byte[fis.available()];
            int read;
            read = fis.read(buffer);
            log.info("写出{}字节", read);
            fis.close();
            //将pdf复制到已创建文档中
            if (read != 0) {
                pdfCopyToDocument(pdfDoc, document, tempFilePath);
            }


        } catch (Exception e) {
            log.info("Word文件地址{}文件名称{}t_djps_material_task_file表id{}", addFile.get(FILE_PATH), addFile.get(FILE_NAME), addFile.get("id"));
            log.error("Word文件找不到", e);
        }
    }

    private void addImg(Document document, PdfFont font, List<Map<String, Object>> imgList) {
        log.info("图片数量:{}", imgList.size());
        for (Map<String, Object> file : imgList) {
            String fileRealPath = taskFilePath + File.separator + getObjectString(file.get(FILE_PATH)).replace("/file/", "").replace("/", File.separator);
//                                    检查文件是否存在
            if (!new File(fileRealPath).exists()) {
                log.info("文件找不到:{}", fileRealPath);
            } else {
                try {
                    log.info("================开始拼接图片,文件id:{}=========", file.get("id"));
                    // 加载本地图片
                    // 加载图片文件并添加到文档中
                    ImageData imageData = ImageDataFactory.create(fileRealPath);
                    // 注意这里使用了Image类的静态方法create()来创建图片实例
                    new Image(imageData);
                    Image img = new Image(imageData);
                    // 设置图片的缩放比例
                    img.setHeight(200);
                    img.setWidth(200);
                    // 文件名称
                    document.add(
                            new Paragraph(
                                    new Text(getObjectString(file.get(FILE_NAME))
                                    ).setFont(font)
                            ));
                    document.add(img);

                } catch (Exception e) {
                    log.info("图片文件地址{}文件名称{}t_djps_material_task_file表id{}", file.get(FILE_PATH), file.get(FILE_NAME), file.get("id"));
                    log.error("图片文件找不到", e);
                }
            }
        }
    }

    public String objectToString(Object s) {
        if (s == null) {
            return "--";
        }
        return String.valueOf(s);
    }

3.很重要! 这个方法实现了将pdf内容复制到创建的文档中

    private void pdfCopyToDocument(PdfDocument pdfDoc, Document document, String fileRealPath) {
        // 读取PDF文件
        try {
            //读取已存在的PDF文档 (文档2) 并准备复制其页面
            PdfDocument pdfDoc2 = new PdfDocument(new PdfReader(fileRealPath));
            int numberOfPages = pdfDoc2.getNumberOfPages();
            if (numberOfPages == 0) {
                return;
            }
            // Step 4: 复制文档2的每一页到文档1
            for (int i = 1; i <= numberOfPages; i++) {
                PdfPage page = pdfDoc2.getPage(i).copyTo(pdfDoc);
                pdfDoc.addPage(page); // 在某些iText版本中,copyTo可能已经自动添加了页面
            }
            pdfDoc2.close();
            //添加空页面 避免新加内容出现在复制的pdf上
            for (int i = 1; i <= numberOfPages; i++) {
                document.add(new AreaBreak(AreaBreakType.NEXT_AREA));
            }

        } catch (Exception e) {
            log.error("文件找不到", e);
        }
    }

4.word转pdf

    import com.aspose.cells.PageSetup;
import com.aspose.cells.PaperSizeType;
import com.aspose.cells.Workbook;
import com.aspose.cells.Worksheet;
import com.aspose.slides.Presentation;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

/**
     * word转pdf
     * inpath: 输入word的路径
     * outpath: 输出pdf的路径
     */
    public void word2Pdf2(String inpath, String outpath) throws Exception {
        if (!getLicense()) {
            return;
        }
        File file = new File(outpath);
        if (file.exists() && file.isFile() && (file.length() > 0)) {
            return;
        }
        FileOutputStream os = new FileOutputStream(file);
        //解决乱码
        //如果是windows执行,不需要加这个
        //如果是linux执行,需要添加这个字体路径
        //FontSettings.setFontsFolder("/usr/share/fonts",true);
        String property = System.getProperty("os.name");
        Document doc = new Document(inpath);
        log.info("os.name:" + property);
        if (property.startsWith("Linux")) {
            FontSettings fontSettings = new FontSettings();
            fontSettings.setFontsFolder("/usr/share/fonts", true);
            doc.setFontSettings(fontSettings);
        }
        //全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
        doc.save(os, SaveFormat.PDF);
        os.close();
    }

5.excel转pdf

 import com.aspose.cells.PageSetup;
import com.aspose.cells.PaperSizeType;
import com.aspose.cells.Workbook;
import com.aspose.cells.Worksheet;
import com.aspose.slides.Presentation;
import com.aspose.words.Document;
import com.aspose.words.FontSettings;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

 public void excel2Pdf(String path, String outpath) throws FileNotFoundException {
        if (!getLicenseExcel()) {
            return;
        }

        File file = new File(outpath);
        if (file.exists() && file.isFile() && (file.length() > 0)) {
            return;
        }
        try (FileOutputStream fileOutputStream = new FileOutputStream(file)) {
            Workbook wb = new Workbook(path);

            //设置纸张大小为A3解决excel转pdf 一页内容被分割成多页pdf
            // 遍历所有工作表
            for (int i = 0; i < wb.getWorksheets().getCount(); i++) {
                Worksheet worksheet = wb.getWorksheets().get(i);
                // 获取页面设置
                PageSetup pageSetup = worksheet.getPageSetup();
                // 设置纸张大小为A3
                pageSetup.setPaperSize(PaperSizeType.PAPER_A_3);
            }
            wb.save(fileOutputStream, com.aspose.cells.SaveFormat.PDF);
        } catch (Exception e) {
            log.error("excel2Pdf error", e);
        }
    }

创建临时文件

   /**
     * 创建临时文件(解决安全热点问题)
     *
     * @param fileName 文件名
     * @param fileType 文件类型
     * @return 临时文件
     */
    public File getTempFile(String fileName, String fileType) {
        File resultFile = null;
        try {
            if(SystemUtils.IS_OS_UNIX) {
                log.info("IS_OS_UNIX临时文件开始=======");
                FileAttribute<Set<PosixFilePermission>> attr = PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rwx------"));
                resultFile = Files.createTempFile(fileName, fileType , attr).toFile();
            }
            else {
                resultFile = Files.createTempFile(fileName, fileType).toFile();
                boolean readAble = resultFile.setReadable(true, true);
                boolean writable = resultFile.setWritable(true, true);
                boolean executable = resultFile.setExecutable(true, true);
                if (readAble && writable && executable) {
                    log.info("临时文件权限设置成功");
                }
            }
        } catch (Exception e) {
            log.info("材料文件转换失败WordToPdf: {}", e.getMessage());
        }
        return resultFile;
    }
 <!--Aspose相关依赖 需要在本地指定导入-->
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>cells</artifactId>
            <version>8.5.2</version>
        </dependency>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>slides</artifactId>
            <version>15.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.aspose</groupId>
            <artifactId>words.jdk16</artifactId>
            <version>16.8.0</version>
        </dependency>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值