【Java】利用 PDF 多页模板生成多个 PDF 后压缩成 ZIP 并导出

一、所需要的依赖

<dependencies>
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>5.3.8</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>5.5.11</version>
   	</dependency>
</dependencies>

二、工具类代码

package ...

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class PdfUtil {
    
    /**
     * 根据模板生成多个 pdf 并压缩为 zip 文件
     *
     * @param templateName 模板名称(在 resources 文件夹下)
     * @param zipName      压缩包名称
     * @param map          String:传文件名,Object:传 Map<String, String> 对应 pdf 模板里面的字段值
     * @param response     响应对象
     */
    public static void pdfExportPagePlus(String templateName, String zipName, Map<String, Object> map, HttpServletResponse response) {
        OutputStream out = null;
        try {
            // String:被压缩的文件名,byte[]:被压缩的文件流
            List<Map<String, byte[]>> baisBytes = CollUtil.newArrayList();
            for (String fileName : map.keySet()) {
                Map<String, String> inputMap = Convert.toMap(String.class, String.class, map.get(fileName));
                // 将生成 pdf 转化为输入流返回
                ByteArrayOutputStream bos = new ByteArrayOutputStream();

                // 读取pdf模板
                InputStream inputStream = PdfUtil.class.getClassLoader().getResourceAsStream(templateName);

                PdfReader reader = new PdfReader(inputStream);
                PdfStamper stamper = new PdfStamper(reader, bos);
                // 获取模板所有域参数
                AcroFields form = stamper.getAcroFields();
                // 解决中文字体不显示的问题
                BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                ArrayList<BaseFont> fontArrayList = new ArrayList<BaseFont>();
                fontArrayList.add(baseFont);
                form.setSubstitutionFonts(fontArrayList);
                // 文字类的内容处理
                for (String key : inputMap.keySet()) {
                    String value = inputMap.get(key);
                    form.setField(key, value);
                }
                stamper.setFormFlattening(true);
                stamper.close();
                reader.close();

                byte[] xmpMetadata = bos.toByteArray();
                HashMap<String, byte[]> insertMap = MapUtil.newHashMap();
                insertMap.put(fileName, xmpMetadata);
                baisBytes.add(insertMap);
            }

            // -------------------- 多个 pdf 压缩在 zip 里面  ------------------------

            // 1.创建字节数组输出流,用于返回压缩后的输出流字节数组
            out = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(zipName, "UTF-8"));
            // 2.创建压缩输出流
            ZipOutputStream zipOutStream = new ZipOutputStream(out);
            // 3.遍历要批量压缩的集合文件流
            ByteArrayInputStream bais;
            String fileName;
            int temp;
            for (Map<String, byte[]> tempMap : baisBytes) {
                fileName = tempMap.keySet().iterator().next();
                // 3.1.将需要压缩的字节输出流,转为字节数组输入流
                bais = new ByteArrayInputStream(tempMap.get(fileName));
                // 3.2.设置ZipEntry对象,并对需要压缩的文件命名
                zipOutStream.putNextEntry(new ZipEntry(fileName));
                // 3.3.读取要压缩的字节输出流,进行压缩
                while ((temp = bais.read()) != -1) {
                    // 压缩输出
                    zipOutStream.write(temp);
                }
                // 3.4.关闭流
                bais.close();
            }
            // 4.关闭流
            zipOutStream.close();
        } catch (IOException | DocumentException e) {
            System.out.println(e);
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

三、参考

使用 java.util.zip 对生成的 ByteArrayOutputStream(字节数组输出文件流)进行打包压缩(单个、批量),并返回压缩包文件的字节数组输出文件流用于(文件不落地)下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,可以使用Apache POI库来读取和操作Excel文件,并使用JavaZipOutputStream类将这些Excel文件压缩成ZIP文件。 首先,需要确保已经将Apache POI库添加到项目的依赖中。 然后,可以使用POI库中的Workbook类来读取和写入Excel文件。通过循环读取每个Excel文件,并使用ZipOutputStream类将它们压缩到ZIP文件中。 下面是一个示例代码: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class ExcelZipper { public static void main(String[] args) { // 指定需要压缩的Excel文件路径 String[] excelPaths = {"excel1.xlsx", "excel2.xlsx"}; // 指定压缩后的ZIP文件路径 String zipPath = "compressed.zip"; try { FileOutputStream fos = new FileOutputStream(zipPath); ZipOutputStream zos = new ZipOutputStream(fos); for (String excelPath : excelPaths) { FileInputStream fis = new FileInputStream(excelPath); Workbook workbook = new XSSFWorkbook(fis); // 将每个Excel文件写入到ZIP文件中 ZipEntry ze = new ZipEntry(excelPath); zos.putNextEntry(ze); workbook.write(zos); workbook.close(); fis.close(); } zos.close(); fos.close(); System.out.println("Excel文件已压缩成ZIP文件成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 上述代码中,需要将"excel1.xlsx"和"excel2.xlsx"替换为实际的Excel文件路径。压缩后的ZIP文件将保存为"compressed.zip"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值