依赖包itextpdf:5.5.6
package com.changfu.common.util;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.ResourceUtils;
import java.io.*;
import java.util.Map;
/**
* PDF生成工具类
* Created by J.W on 2017/4/17 0017.
*/
@Slf4j
public class PDFUtil {
public static final String FORMAT = ".pdf";
private static final String DEFAULT_WINDOWS_PATH = "D:\\data\\contract";
private static final Boolean IS_WINDOWS_OS = System.getProperty("os.name").startsWith("Windows");
/**
* 生成pdf
* @param targetPath 目标路径
* @param targetName 目标名称(不要带后缀名)
* @param fieldsMap 表单填充数据集合
* @param sealsMap 图片填充集合 例: Key:"partyASeal" value:"http://xxxx.png"
*/
public static File createPDF(String templateName,
String targetPath,
String targetName,
Map<String, String> fieldsMap,
Map<String, String> sealsMap) throws IOException, DocumentException {
PdfReader reader = null;
PdfStamper stamper = null;
InputStream is = null;
OutputStream output = null;
try {
is = PDFUtil.class.getClassLoader().getResourceAsStream(templateName);
log.info("获取模板字节流[{}]", is);
// File templateFile = ResourceUtils.getFile(templateName);
// inputStream = new FileInputStream(templateFile);
String targetFilePath = null;
if(IS_WINDOWS_OS) {
targetFilePath = DEFAULT_WINDOWS_PATH + File.separator + targetName + FORMAT;
} else {
targetFilePath = targetPath + File.separator + targetName + FORMAT;
}
reader = new PdfReader(is);
File targetFile = new File(targetFilePath);
if(!targetFile.getParentFile().isDirectory()) {
log.info("创建合同文件[{}]", targetFile.getAbsolutePath());
targetFile.getParentFile().mkdirs();
}
if(!targetFile.exists()) {
log.info("创建合同文件[{}]", targetFile.getAbsolutePath());
targetFile.createNewFile();
}
output = new FileOutputStream(targetFile);
stamper = new PdfStamper(reader, output);
AcroFields acroFields = stamper.getAcroFields();
//给表单添加中文字体 这里采用系统字体。不设置的话,中文可能无法显示
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
// BaseFont bf = null;
// if(IS_WINDOWS_OS) {
// bf = BaseFont.createFont("C:\\Windows\\Fonts\\SIMSUN.TTC,1",BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// } else {
// bf = BaseFont.createFont("C:\\Windows\\Fonts\\SIMSUN.TTC,1",BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
// }
acroFields.addSubstitutionFont(bf);
// 开始填充表单
for(Map.Entry<String, String> entry : fieldsMap.entrySet()) {
if(entry.getValue() == null) {
continue;
}
acroFields.setField(entry.getKey(), entry.getValue());
}
// 填充图片
for(Map.Entry<String, String> entry : sealsMap.entrySet()) {
if(entry.getValue() == null) {
continue;
}
int pageNo = acroFields.getFieldPositions(entry.getKey()).get(0).page;
Rectangle rectangle = acroFields.getFieldPositions(entry.getKey()).get(0).position;
float x = rectangle.getLeft();
float y = rectangle.getBottom();
// 读图片
Image image = Image.getInstance(entry.getValue());
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(rectangle.getWidth(), rectangle.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
stamper.setFormFlattening(true);
return targetFile;
} catch (Exception e) {
log.error("生成pdf失败 templateName={}, targetName={}", templateName, targetName, e);
throw e;
} finally {
try {
stamper.close();
} catch (Exception e) {
stamper = null;
}
try {
reader.close();
} catch (Exception e) {
reader = null;
}
try {
output.close();
} catch (Exception e) {
output = null;
}
try {
is.close();
} catch (Exception e) {
is = null;
}
}
}
}
@RequestMapping("downloadContract/{id}")
@RequiresPermissions("tcTransaction:index")
@ResponseBody
public String downloadContract(Model model,
@PathVariable("id") Long id) {
return tcContractService.downloadContract(id);
}