准备模版
- 使用 福昕高级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文件还能编辑,所以一定要设为truepdfStamper.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 和 contentTyperesponse.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 随笔