准备模版
- 使用 福昕高级PDF编辑器 (本人用的这个,其他的也行,能作模版就行)
- 打开PDF文件点击 表单 选项,点击 文本域
- 在需要填充数据的位置设计文本域
- 设置 名称、提示
- 名称相当于 属性名,提示就是提示,说明这个是什么
导入依赖
<!--itext-->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.4.2</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.13</version>
</dependency>
函数编写
generatePdf
放 ServiceIMpl 里就行,这个是直接浏览器下载生成后的附件
private final HttpServletResponse response;
public PdfServiceImpl(HttpServletResponse response) {
this.response = response;
}
public void generatePdf(Map<String, String> params) {
// 读取资源文件夹下的模板
ClassPathResource resource = new ClassPathResource("pdf-template/文件.pdf");
InputStream inputStream = resource.getInputStream();
PdfReader reader = null;
ByteArrayOutputStream bos = null;
try {
reader = new PdfReader(inputStream);
bos = new ByteArrayOutputStream();
PdfStamper pdfStamper = new PdfStamper(reader, bos);
AcroFields acroFields = pdfStamper.getAcroFields();
// 字体设置
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
for (Map.Entry<String, String> param : params.entrySet()) {
// 设置文本域的字体为中文字体
acroFields.setFieldProperty(param.getKey(), "textFont", font, null);
// 将 map 中的值写到 pdf 模板对应的文本域中
acroFields.setField(param.getKey(), param.getValue());
}
// 如果为false那么生成的PDF文件还能编辑,所以一定要设为true
pdfStamper.setFormFlattening(true);
pdfStamper.close();
// 返回文件
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(bos.toByteArray());
ServletUtils.writeAttachment(response, "新文件.pdf", bos.toByteArray());
} catch (IOException | DocumentException e) {
e.printStackTrace();
} finally {
try {
assert bos != null;
bos.close();
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
工具类
ServletUtils
import cn.hutool.core.io.IoUtil;
import org.springframework.http.MediaType;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
/**
* @Package_Name com.lesliecheung.javacase.util.pdf
* @Author Leslie Lee
* @TIME
* @Version
*/
public class ServletUtils {
/**
* 返回附件
*
* @param response 响应
* @param filename 文件名
* @param content 附件内容
*/
public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
// 设置 header 和 contentType
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
// 输出附件
IoUtil.write(response.getOutputStream(), false, content);
}
}
获取模版 inputStream 流
从url下载文件
// 获取文件地址
String urlPath = "模板资源文件链接-url";
// 下载文件
URL url = new URL(urlPath);
URLConnection connection = url.openConnection();
// 设置请求超时时长为 5 秒
connection.setConnectTimeout(5*1000);
// 读取数据
InputStream inputStream = connection.getInputStream();
从某路径下直接取
String urlPath = "D:\\文件.pdf";
File file1 = new File(urlPath);
InputStream inputStream = new FileInputStream(file1);
新文件写入其他位置,操作 bos.toByteArray() 就好了
File file = new File("D:/新文件.pdf");
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream boss = new BufferedOutputStream(fos);
boss.write(bos.toByteArray());
fos.close();
boss.close();
System.out.println("成了");
Leslie Lee 随笔