|
@@ -0,0 +1,206 @@
|
|
|
|
|
+package com.zksy.basicData.utils;
|
|
|
|
|
+
|
|
|
|
|
+import com.itextpdf.text.Document;
|
|
|
|
|
+import com.itextpdf.text.DocumentException;
|
|
|
|
|
+import com.itextpdf.text.Image;
|
|
|
|
|
+import com.itextpdf.text.Rectangle;
|
|
|
|
|
+import com.itextpdf.text.pdf.*;
|
|
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
+
|
|
|
|
|
+import java.io.*;
|
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
|
+import java.util.HashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+
|
|
|
|
|
+public class PdfUtil {
|
|
|
|
|
+
|
|
|
|
|
+ /**htmlT
|
|
|
|
|
+ * 填充pdf
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param inputStream pdf模板
|
|
|
|
|
+ * @param createFileUrl 创建的pdf存放路径 (如果为空则不会写入)
|
|
|
|
|
+ * @param dataMap 文字替换map
|
|
|
|
|
+ * @return
|
|
|
|
|
+ * @throws Exception
|
|
|
|
|
+ */
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ public static byte[] fillPdf(InputStream inputStream, String createFileUrl, Map<String, String> dataMap) throws Exception {
|
|
|
|
|
+ PdfReader reader = new PdfReader(inputStream);
|
|
|
|
|
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
|
|
|
|
+ /* 将要生成的目标PDF文件名称 */
|
|
|
|
|
+ PdfStamper ps = new PdfStamper(reader, bos);
|
|
|
|
|
+
|
|
|
|
|
+ //使用中文字体
|
|
|
|
|
+ BaseFont bf = BaseFont.createFont("simsun.ttc,0" , BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
|
|
|
|
+ ArrayList<BaseFont> fontList = new ArrayList<BaseFont>();
|
|
|
|
|
+ fontList.add(bf);
|
|
|
|
|
+
|
|
|
|
|
+ /* 取出报表模板中的所有字段 */
|
|
|
|
|
+ AcroFields fields = ps.getAcroFields();
|
|
|
|
|
+ fields.setSubstitutionFonts(fontList);
|
|
|
|
|
+ if (dataMap != null){
|
|
|
|
|
+ //替换文字
|
|
|
|
|
+ fillData(fields, dataMap);
|
|
|
|
|
+ }
|
|
|
|
|
+ /* 必须要调用这个,否则文档不会生成的 */
|
|
|
|
|
+ ps.setFormFlattening(true);
|
|
|
|
|
+ ps.close();
|
|
|
|
|
+
|
|
|
|
|
+ byte[] bytes = bos.toByteArray();
|
|
|
|
|
+ if (StringUtils.isNotBlank(createFileUrl)) {
|
|
|
|
|
+ OutputStream fos = new FileOutputStream(createFileUrl);
|
|
|
|
|
+ fos.write(bytes);
|
|
|
|
|
+ fos.flush();
|
|
|
|
|
+ fos.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ bos.close();
|
|
|
|
|
+ reader.close();
|
|
|
|
|
+ return bytes;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 填充数据
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param fields
|
|
|
|
|
+ * @param data
|
|
|
|
|
+ * @throws IOException
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void fillData(AcroFields fields, Map<String, String> data)
|
|
|
|
|
+ throws IOException {
|
|
|
|
|
+ for (String key : data.keySet()) {
|
|
|
|
|
+ String value = data.get(key);
|
|
|
|
|
+ try {
|
|
|
|
|
+ fields.setField(key, value); // 为字段赋值,注意字段名称是区分大小写的
|
|
|
|
|
+ } catch (com.itextpdf.text.DocumentException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 填充图片
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param stamper
|
|
|
|
|
+ * @param fields
|
|
|
|
|
+ * @param imageMap
|
|
|
|
|
+ * @throws Exception
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void fillImage(PdfStamper stamper, AcroFields fields, Map<String, byte[]> imageMap) throws Exception {
|
|
|
|
|
+ for (String fieldName : imageMap.keySet()
|
|
|
|
|
+ ) {
|
|
|
|
|
+ // 通过域名获取所在页和坐标,左下角为起点
|
|
|
|
|
+ int pageNo = fields.getFieldPositions(fieldName).get(0).page;
|
|
|
|
|
+ Rectangle signRect = fields.getFieldPositions(fieldName).get(0).position;
|
|
|
|
|
+ float x = signRect.getLeft();
|
|
|
|
|
+ float y = signRect.getBottom();
|
|
|
|
|
+
|
|
|
|
|
+ // 读图片
|
|
|
|
|
+ Image image = Image.getInstance(imageMap.get(fieldName));
|
|
|
|
|
+ // 获取操作的页面
|
|
|
|
|
+ PdfContentByte under = stamper.getOverContent(pageNo);
|
|
|
|
|
+ // 根据域的大小缩放图片
|
|
|
|
|
+ image.scaleToFit(signRect.getWidth(), signRect.getHeight());
|
|
|
|
|
+ // 添加图片
|
|
|
|
|
+ y = signRect.getTop() - image.getPlainHeight();//使图片出现在左上角
|
|
|
|
|
+ image.setAbsolutePosition(x, y);
|
|
|
|
|
+ under.addImage(image);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获得指定文件的byte数组
|
|
|
|
|
+ */
|
|
|
|
|
+ public static byte[] getBytes(String filePath) {
|
|
|
|
|
+ byte[] buffer = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ File file = new File(filePath);
|
|
|
|
|
+ FileInputStream fis = new FileInputStream(file);
|
|
|
|
|
+ ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
|
|
|
|
|
+ byte[] b = new byte[1000];
|
|
|
|
|
+ int n;
|
|
|
|
|
+ while ((n = fis.read(b)) != -1) {
|
|
|
|
|
+ bos.write(b, 0, n);
|
|
|
|
|
+ }
|
|
|
|
|
+ fis.close();
|
|
|
|
|
+ bos.close();
|
|
|
|
|
+ buffer = bos.toByteArray();
|
|
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ }
|
|
|
|
|
+ return buffer;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static Map<String, byte[]> dataMap() {
|
|
|
|
|
+ Map<String, byte[]> data = new HashMap<>();
|
|
|
|
|
+ data.put("LEADERSHIP_INSTRUCTIONS_NAME", getBytes("H:/PDF/name.png"));
|
|
|
|
|
+ data.put("ACCEPTANCE_SITUATION", getBytes("H:/PDF/name2.png"));
|
|
|
|
|
+ data.put("INSTALL_USER", getBytes("H:/PDF/name3.png"));
|
|
|
|
|
+ data.put("PAYMENT_RECORDS", getBytes("H:/PDF/name4.png"));
|
|
|
|
|
+ data.put("MATERIALS_BUDGET", getBytes("H:/PDF/name5.png"));
|
|
|
|
|
+ return data;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 根据byte进行合并
|
|
|
|
|
+ * @param byteList 需要合并的pdf列表(文件流) byte
|
|
|
|
|
+ * @param strList 需要合并的pdf列表(文件地址) String
|
|
|
|
|
+ * @param savePath 保存路径(文件流输出路径) FileOutputStream
|
|
|
|
|
+ */
|
|
|
|
|
+ public static void mergeAccording(List<byte[]> byteList, List<String> strList, String savePath) {
|
|
|
|
|
+ Document document = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ List<byte[]> fileList = new ArrayList<>();
|
|
|
|
|
+ if (CollectionUtils.isNotEmpty(byteList)){
|
|
|
|
|
+ fileList = byteList;
|
|
|
|
|
+ }else{
|
|
|
|
|
+ for (String s : strList) {
|
|
|
|
|
+ fileList.add(getBytes(s));
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ document = new Document(new PdfReader(fileList.get(0)).getPageSize(1));
|
|
|
|
|
+ PdfCopy copy = new PdfCopy(document, new FileOutputStream(savePath));
|
|
|
|
|
+ document.open();
|
|
|
|
|
+ for (int i = 0; i < fileList.size(); i++) {
|
|
|
|
|
+ PdfReader reader = new PdfReader(fileList.get(i));
|
|
|
|
|
+ int n = reader.getNumberOfPages();// 获得总页码
|
|
|
|
|
+ for (int j = 1; j <= n; j++) {
|
|
|
|
|
+ document.newPage();
|
|
|
|
|
+ PdfImportedPage page = copy.getImportedPage(reader, j);// 从当前Pdf,获取第j页
|
|
|
|
|
+ copy.addPage(page);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ } catch (DocumentException e) {
|
|
|
|
|
+ e.printStackTrace();
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ if (document != null) {
|
|
|
|
|
+ document.close();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+/* static String savepath = "E:\\IdeaProjects\\water\\attachment\\resource\\20190413\\R190413101922623.pdf";
|
|
|
|
|
+
|
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
|
+ List<String> fileList = getFiles();
|
|
|
|
|
+ mergeAccording(null, fileList, savepath);
|
|
|
|
|
+ System.out.println(getBytes(savepath));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static List<String> getFiles() {
|
|
|
|
|
+ List<String> fileList = new ArrayList<String>();
|
|
|
|
|
+ fileList.add("E:\\IdeaProjects\\water\\attachment\\resource\\20190413\\R190413093901966.pdf\\");
|
|
|
|
|
+ fileList.add("E:\\IdeaProjects\\water\\attachment\\resource\\20190413\\R190413093902569.pdf\\");
|
|
|
|
|
+ fileList.add("E:\\IdeaProjects\\water\\attachment\\resource\\20190413\\R190413093902764.pdf\\");
|
|
|
|
|
+ fileList.add("E:\\IdeaProjects\\water\\attachment\\resource\\20190413\\R190413093902721.pdf\\");
|
|
|
|
|
+ return fileList;
|
|
|
|
|
+ }*/
|
|
|
|
|
+
|
|
|
|
|
+}
|