java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java itext5生成PDF

Java使用itext5实现生成多个PDF并合并

作者:秋夜雨巷

这篇文章主要为大家详细介绍了Java如何使用itext5实现生成多个PDF并合并,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

PDF批量生成并合并为1个PDF

单个生成

    /**
     * 根据id查询数据
     * @param id 数据id
     * @return
     */
    private Map<String, String> queryEntityDataById(String id) {
        //根据id查询
        Box entity = BoxService.getById(id);

        Map<String, String> data = new HashMap<String, String>();
        //显示内容
        //id
        data.put("id", entity.getJdKh());
        //动态生成当前时间的yymmddhh格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMddHH");
        String currentDate = LocalDateTime.now().format(formatter);
        data.put("date", currentDate);

        //二维码内容
        data.put("imsi", entity.getImsi());
        data.put("imei", entity.getImei());

        String type = entity.getType();
        if (type == null || type.isEmpty()) {
            type = "A";
        }
        data.put("type", type);
        return data;
    }

    //根据数据生成PDF
    private void generatePdfForData(Map<String, String> data, ByteArrayOutputStream outputStream) throws Exception {
        // Load the PDF template
        InputStream templateStream = getClass().getResourceAsStream("/template/ddentitytemplate.pdf");
        PdfReader reader = new PdfReader(templateStream);
        PdfStamper stamper = new PdfStamper(reader, outputStream);

        AcroFields form = stamper.getAcroFields();
        String fontPath = File.separator + "font" + File.separator + "micosoftyh.ttf";
        BaseFont bfChinese = BaseFont.createFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        Map<String, AcroFields.Item> fields = form.getFields();
        for (String k : fields.keySet()) {
            form.setFieldProperty(k, "textfont", bfChinese, null);
            form.setFieldProperty(k, "textsize", Float.valueOf("55"), null);
            form.setFieldProperty(k, "textstyle", com.itextpdf.text.Font.BOLD, null);
            form.setFieldProperty(k, "textalign", Element.ALIGN_MIDDLE, null);
        }
        //特殊文本框字体大小重置
        form.setFieldProperty("$serialnumber$", "textsize", Float.valueOf("40"), null);
        //标签内容
        //ID
        form.setField("$id$", data.get("id"));
        //日期
        form.setField("$date$", data.get("date"));

        //二维码
        String qrContent = String.format(
                        "ID:%s\n" +
                        "IMSI:%s\n" +
                        "IMEI:%s\n" +
                        "type:%s",
                data.get("id"), data.get("imsi"), data.get("imei"),data.get("type"));
        PdfContentByte cb = stamper.getOverContent(1);
        generateQRcode(qrContent, cb);
        stamper.setFormFlattening(true);
        stamper.close();
        reader.close();
    }

返回PDF

    /**
     * 根据ID批量生成pdf并合并
     * @param ids ids集合
     * @return 可直接访问的pdf流文件
     */
    @GetMapping("/generateMergePdfStream")
    public ResponseEntity<ByteArrayResource> generateMergePdfStream(@RequestParam String ids) {
        long startTime = System.currentTimeMillis();
        System.out.println("开始生成PDF: " + startTime);
        try {
            String[] idArray = ids.split(",");
            ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
            Document mergedDocument = new Document();
            PdfSmartCopy copy = new PdfSmartCopy(mergedDocument, mergedOutputStream);
            mergedDocument.open();

            for (String id : idArray) {
                Map<String, String> data = queryEntityDataById(id.trim());

                ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
                generatePdfForData(data, pdfOutputStream);

                System.out.println("生成的PDF文件大小: " + pdfOutputStream.size());

                PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfOutputStream.toByteArray()));
                copy.addDocument(reader);
                reader.close();
                pdfOutputStream.close();
            }

            mergedDocument.close();

            ByteArrayResource resource = new ByteArrayResource(mergedOutputStream.toByteArray());

            HttpHeaders headers = new HttpHeaders();
            headers.add("Content-Disposition", "inline; filename=merged.pdf");

            long generationEnd = System.currentTimeMillis();
            System.out.println("PDF生成与合并完成,总耗时: " + (generationEnd - startTime) + " 毫秒");

            return ResponseEntity.ok()
                    .headers(headers)
                    .contentType(MediaType.APPLICATION_PDF)
                    .body(resource);

        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(500).build();
        }
    }

文件保存在本地通过http接口访问pdf文件

application.properties

#访问jar包位置的同级files文件,可以直接通过http://IP:port/files下的文件名访问
spring.web.resources.static-locations=file:./files/

合并PDF并保存

    /**
     * 生成合并的pdf文件保存到服务器下面
     * application.properties下面需要配置spring.web.resources.static-locations=file:./files/
     * jar包运行的文件夹目录
     * @param ids ids集合
     * @return 可直接访问的http://IP:Port/*.pdf
     */
    @GetMapping("/generateentityLogPdf")
    public ResponseEntity generateMergeSavePdf(@RequestParam String ids, HttpServletRequest request) {
        try {
            // 分割ids
            String[] idArray = ids.split(",");

            // 输出流
            ByteArrayOutputStream mergedOutputStream = new ByteArrayOutputStream();
            Document mergedDocument = new Document();
            PdfCopy copy = new PdfCopy(mergedDocument, mergedOutputStream);
            mergedDocument.open();

            for (String id : idArray) {
                //根据id查询pdf所需要数据
                Map<String, String> data = queryEntityDataById(id.trim());

                // 根据id生成pdf数据流
                ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();
                generatePdfForData(data, pdfOutputStream);

                // 将生成的pdf数据流
                PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfOutputStream.toByteArray()));
                copy.addDocument(reader);
                reader.close();
            }

            mergedDocument.close();

            //保存文件路径
            String currentDateDir = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            // 获取运行目录下的 files 目录路径
            String filePath = System.getProperty("user.dir") + File.separator + "files" + File.separator + currentDateDir;
            File directory = new File(filePath);

            // 检查目录是否存在,不存在则创建
            if (!directory.exists()) {
                directory.mkdirs();
            }

            // 保存文件名
            Random random = new Random();
            int randomNumber = random.nextInt(1000);
            String fileName = System.currentTimeMillis() + "_" + randomNumber + ".pdf";

            File file = new File(directory, fileName);
            try (FileOutputStream fos = new FileOutputStream(file)) {
                fos.write(mergedOutputStream.toByteArray());
                fos.flush();
                System.out.println("文件保存成功:" + file.getAbsolutePath());
            } catch (IOException e) {
                e.printStackTrace();
            }
            //返回直接访问pdf的url
            String ip = request.getServerName();
            int port = request.getServerPort();
            String fileUrl = "http://" + ip + ":" + port + "/" + currentDateDir + "/" + fileName;
            return ResponseEntity.ok(fileUrl);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(500).build();
        }
    }

出现问题PDF文件过大

解决办法:

提取字体子集

到此这篇关于Java使用itext5实现生成多个PDF并合并的文章就介绍到这了,更多相关Java itext5生成PDF内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文