JAVA操作PDF文件

PDF插入表单或图片

PDF插入表单数据前需要对模板进行处理,使用Adobe Acrobat DC 的准备表单功能添加文本域
表单数据MAP里的KEY必须与PDF添加的域名称一致才能添加进去
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.HashMap;

 /**
     * @param templateFilePath PDF模版文件路径
     * @param data             表单数据
     * @param imageData        图片文件路径
     * @param disableEditing   生成后的PDF文件 true不可编辑  false可编辑
     * @param pdfFilePath      生成后PDF文件路径
     * @throws Exception
     */
    @Test
    void test(String templateFilePath, HashMap<String, String> data, HashMap<String, String> imageData, boolean disableEditing, String pdfFilePath) throws Exception {
        PdfReader reader = null;
        ByteArrayOutputStream bos = null;
        PdfStamper pdfStamper = null;
        FileOutputStream fos = null;
        try {
            // 读取PDF模版文件
            reader = new PdfReader(templateFilePath);
            // 输出流
            bos = new ByteArrayOutputStream();
            // 构建PDF对象
            pdfStamper = new PdfStamper(reader, bos);

            // 获取表单数据
            AcroFields form = pdfStamper.getAcroFields();

            // 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体 Adobe 宋体 std L
            BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            form.addSubstitutionFont(bfChinese);
            if (data != null && data.size() > 0) {
                // 表单赋值
                for (String key : data.keySet()) {
                    form.setField(key, data.get(key));
                    // 也可以指定字体
                    form.setFieldProperty(key, "textfont", bfChinese, null);
                }
            }
            // 添加图片
            if (null != imageData && imageData.size() > 0) {
                for (String key : imageData.keySet()) {
                    int pageNo = form.getFieldPositions(key).get(0).page;
                    Rectangle signRect = form.getFieldPositions(key).get(0).position;
                    float x = signRect.getLeft();
                    float y = signRect.getBottom();
                    // 读图片
                    Image image = Image.getInstance(imageData.get(key));
                    // 获取操作的页面
                    PdfContentByte under = pdfStamper.getOverContent(pageNo);
                    // 根据域的大小缩放图片
                    image.scaleToFit(signRect.getWidth(), signRect.getHeight());
                    // 添加图片
                    image.setAbsolutePosition(x, y);
                    under.addImage(image);
                }
            }
            pdfStamper.setFormFlattening(disableEditing);
            pdfStamper.close();

            // 保存文件
            fos = new FileOutputStream(pdfFilePath);
            fos.write(bos.toByteArray());
            fos.flush();
        } finally {
            if (null != fos) {
                try {
                    fos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (null != bos) {
                try {
                    bos.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (null != reader) {
                try {
                    reader.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

  <!--itextPDF依赖-->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.13.2</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

PDF转换为图片

多页PDF根据需要可创建文件夹循环存储图片
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

@Test
    void test(String pdfSavePath,String imagePath) throws IOException {
       File newFile = new File(pdfSavePath);
       byte[] bytes = FileUtils.readFileToByteArray(newFile);
       List<byte[]> listByte = pdfToImage(bytes);
       OutputStream oute = new FileOutputStream(new File(imagePath));
       oute.write(listByte.get(0));
       oute.flush();
       oute.close();
   }

	/**
     * PDF转图片
     * @param fileContent PDF文件的二进制流
     * @return 图片文件的二进制流
     */
    public  List<byte[]> pdfToImage(byte[] fileContent) throws IOException {
        // dpi越大转换后越清晰,相对转换速度越慢
        Integer DPI = 300;
        //转换后的图片类型
        String IMG_TYPE = "png";
        List<byte[]> result = new ArrayList<>();
        PDDocument document = PDDocument.load(fileContent);
        ByteArrayOutputStream out =null;
        try  {
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
                out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, IMG_TYPE, out);
                result.add(out.toByteArray());
            }
        }finally {
            out.close();
            document.close();
        }
        return result;
    }
     <!--pdfbox依赖-->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.20</version>
        </dependency>

图片压缩处理

import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.io.FileUtils;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;

@Test
    void test() throws IOException {
        //输入文件
       byte[] bytes = FileUtils.readFileToByteArray(new File("C:\\Users\\LZW\\Desktop\\1.jpg"));
       //根据文件大小调整压缩质量 200*1024=200kb大小
       Float quality = 0.5f;
       if (bytes.length > 200 * 1024 && bytes.length < 2000 * 1024) {
           quality = 0.25f;
       }
       if (bytes.length > 4000 * 1024) {
           quality = 0.2f;
       }
       if (bytes.length > 6000 * 1024) {
           quality = 0.1f;
       }
       if (bytes.length > 10000 * 1024) {
           quality = 0.1f;
       }
       //压缩处理
       ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
       //输出文件
       Thumbnails.of(byteArrayInputStream).scale(1f).outputQuality(quality).toFile("C:\\Users\\LZW\\Desktop\\new.jpg");
   }
   
<!-- 图片压缩处理 -->
        <dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.14</version>
        </dependency>

版权声明:本文为qq_45232584原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。