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>