package com.ltkj.common.utils; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.WriterException; import com.google.zxing.common.BitMatrix; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import org.apache.commons.codec.binary.Base64; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @Company: 西安路泰科技有限公司 * @Author: zhaowenxuan * @Date: 2024/5/24 13:41 */ public class PDFDocumentUtil { /** * 创建document文档对象 * * @return * @throws IOException * @throws DocumentException */ public static Map getDocument() throws IOException, DocumentException { // 创建一个Document对象,并指定A4大小的页面和边距 Document document = new Document(PageSize.A4, 30, 30, 30, 30); // 本地测试文件 打开注释即可 两种都可存在 // String PDF_FILE = "d:\\Users\\w\\Desktop\\test.pdf"; // PdfWriter.getInstance(document, Files.newOutputStream(Paths.get(PDF_FILE))); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); PdfWriter.getInstance(document,outputStream); document.open(); HashMap map = new HashMap<>(); map.put("document",document); map.put("stream",outputStream); return map; } public static Font getFont() throws DocumentException, IOException { // return new Font(BaseFont.createFont("C:\\Windows\\Fonts\\simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED)); return new Font(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED)); } /** * 导检单 * 创建第一个表格为用户信息 * * @param document * @param name * @param sex * @param tjNumber * @param phone * @param danwei * @param time * @throws IOException */ public static void makeUserInfoTable(Document document, String name, String sex , String tjNumber, String phone, String danwei , String time) throws IOException { try { // 两个表格固定都是10列 // 创建基础信息表格 PdfPTable table1 = new PdfPTable(10); table1.setWidthPercentage(100); // 设置列宽 float[] columnWidths = {1.5F, 2, 2, 1, 2, 3, 2, 1, 2, 2}; table1.setWidths(columnWidths); PdfPCell cell; Font font; for (int i = 0; i < 12; i++) { for (int j = 0; j < 10; j++) { if (i == 0 && j == 3) { font = getFont(); font.setStyle(Font.BOLD); font.setSize(24); // 标题 cell = new PdfPCell(new Phrase("体检导检单", font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setColspan(3); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); // 条形码 HashMap map = new HashMap<>(); map.put(EncodeHintType.CHARACTER_SET,"utf-8"); BitMatrix encode = null; try { encode = new MultiFormatWriter().encode(tjNumber, BarcodeFormat.CODE_128, 500, 100, map); } catch (WriterException e) { e.printStackTrace(); } BufferedImage toBufferedImage = MatrixToImageWriter.toBufferedImage(encode); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(toBufferedImage,"png",byteArrayOutputStream); Image image = Image.getInstance(byteArrayOutputStream.toByteArray()); cell = new PdfPCell(image,true); cell.setColspan(4); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); // 添加一行空值 拉开条形码和用户信息的距离 for (int k = 0;k<10;k++){ cell = new PdfPCell(new Phrase(" ")); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); } break; } else if (i == 1 && j == 5) { // 体检号 addKVCell(table1, Font.BOLD, "体检号:", tjNumber, Rectangle.BOTTOM, null, 4, false); break; } else if (i == 2 && j == 0) { addKVCell(table1, Font.BOLD, "姓名:", name, Rectangle.BOTTOM, null, null, false); addKVCell(table1, Font.BOLD, "性别:", sex, Rectangle.BOTTOM, null, null, false); cell = new PdfPCell(new Phrase(" ", getFont())); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); addKVCell(table1, Font.BOLD, "手机号:", phone, Rectangle.BOTTOM, null, 3, false); break; } else if (i == 3 && j == 0) { addKVCell(table1, Font.BOLD, "单位:", danwei, Rectangle.BOTTOM, null, 4, false); addKVCell(table1, Font.BOLD, "登记日期:", time, Rectangle.BOTTOM, null, 3, false); break; } else if (i == 4 && j == 0) { addKVCell(table1, null, "温馨提示:", " ", null, 2, null, true); break; } else if (i == 5 && j == 8) { cell = new PdfPCell(new Phrase("1、采血,腹部彩超检查后方可用餐。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } else if (i == 6 && j == 1) { cell = new PdfPCell(new Phrase("2、近期若有生育计划及未成年人,不宜进行胸片、双能骨密度等放射检查。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } else if (i == 7 && j == 1) { cell = new PdfPCell(new Phrase("3、怀孕或可能已受孕的女士,还应避免妇科、放射科及阴式超声检查。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } else if (i == 8 && j == 1) { cell = new PdfPCell(new Phrase("4、经期女性不宜进行妇科及尿常规检查。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } else if (i == 9 && j == 1) { cell = new PdfPCell(new Phrase("5、若您在等待检查过程中有疑问,请及时联系导检护士。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } else if (i == 10 && j == 1) { cell = new PdfPCell(new Phrase("6、体检结束后请将导检单交还至前台。", getFont())); cell.setColspan(9); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); break; } font = getFont(); cell = new PdfPCell(new Phrase(" ", font)); cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); } } for (PdfPCell pdfPCell : table1.getRows().get(0).getCells()) { try { pdfPCell.setFixedHeight(50); } catch (Exception e) { } } document.add(table1); } catch (DocumentException | IOException e) { e.printStackTrace(); } } /** * 导检单 * 设置键值对 * @param table1 * @param fontStyle 字体样式 * @param title key * @param val val * @param valBottom val是否有下划线 * @param titleCol key跨列 * @param valCol val跨列 * @param isCenter 是否居中 * @throws DocumentException * @throws IOException */ public static void addKVCell(PdfPTable table1, Integer fontStyle , String title, String val, Integer valBottom, Integer titleCol, Integer valCol , boolean isCenter) throws DocumentException, IOException { PdfPCell cell; Font font; font = getFont(); if (fontStyle != null) { font.setStyle(fontStyle); } // 文字居右 cell = new PdfPCell(new Phrase(title, font)); cell.setHorizontalAlignment(Element.ALIGN_RIGHT); if (titleCol != null) { cell.setColspan(titleCol); } if (isCenter) { cell.setHorizontalAlignment(Element.ALIGN_CENTER); } cell.setBorder(Rectangle.NO_BORDER); table1.addCell(cell); font = getFont(); cell = new PdfPCell(new Phrase(val, font)); if (valBottom != null) { cell.setBorder(Rectangle.BOTTOM); } else { cell.setBorder(Rectangle.NO_BORDER); } if (valCol != null) { cell.setColspan(4); } table1.addCell(cell); } /** * 设置导检单 主体信息 * @param * @param * @throws DocumentException * @throws IOException */ public static void makeTjInfo(Document document,List> data) throws DocumentException, IOException { PdfPTable table1 = new PdfPTable(7); table1.setWidthPercentage(100); float[] columnWidths = {1.5f, 3, 3, 6, 1.5f, 3, 3}; table1.setWidths(columnWidths); String[] titleArray = {"序号", "体检科室", "科室位置", "项目", "空腹", "医师签字", "弃检签字"}; Font font = getFont(); font.setStyle(Font.BOLD); for (int i = 0; i < 7; i++) { PdfPCell cell = new PdfPCell(new Phrase(titleArray[i], font)); cell.setFixedHeight(30); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table1.addCell(cell); } font = getFont(); font.setSize(10); for (int i = 0; i < data.size(); i++) { PdfPCell cell = new PdfPCell(new Phrase(String.valueOf(i+1), font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table1.addCell(cell); cell = new PdfPCell(new Phrase((String) data.get(i).get("ksmc"), font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table1.addCell(cell); cell = new PdfPCell(new Phrase((String) data.get(i).get("ksdz"), font)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); table1.addCell(cell); cell = new PdfPCell(new Phrase((String) data.get(i).get("tjxm"), font)); table1.addCell(cell); cell = new PdfPCell(new Phrase(" ", font)); table1.addCell(cell); cell = new PdfPCell(new Phrase(" ", font)); table1.addCell(cell); cell = new PdfPCell(new Phrase(" ", font)); table1.addCell(cell); } document.add(table1); } public static ByteArrayOutputStream execDj(List>> data) throws IOException, DocumentException { Map map = getDocument(); Document document = (Document) map.get("document"); makeUserInfoTable(document, "李四", "女", "189787998", "123456", "单位", "2022-04-21"); List> mapList = data.get(Integer.parseInt("tjInfo")); // makeTjInfo(document, mapList); // 多条则换页 document.newPage(); document.close(); return (ByteArrayOutputStream) map.get("stream"); } /** * 将多个base64pdf合并为一个 * @param base64PdfList pdf集合 * @return */ public static byte[] mergePDFs(List base64PdfList) throws DocumentException, IOException { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); Document document = new Document(); PdfCopy copy = new PdfCopy(document, byteArrayOutputStream); document.open(); for (String base64Pdf : base64PdfList) { byte[] pdfBytes = Base64.decodeBase64(base64Pdf); PdfReader reader = new PdfReader(new ByteArrayInputStream(pdfBytes)); int numberOfPages = reader.getNumberOfPages(); for (int i = 1; i <= numberOfPages; i++) { document.newPage(); PdfImportedPage page = copy.getImportedPage(reader, i); copy.addPage(page); } reader.close(); } document.close(); return byteArrayOutputStream.toByteArray(); } }