|
|
@@ -0,0 +1,267 @@
|
|
|
+package com.xunmei.file.utils;
|
|
|
+
|
|
|
+
|
|
|
+import cn.hutool.core.io.resource.ClassPathResource;
|
|
|
+import com.lowagie.text.*;
|
|
|
+import com.lowagie.text.pdf.*;
|
|
|
+import com.xunmei.file.vo.ItextPdfTableVo;
|
|
|
+
|
|
|
+import java.io.File;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public class PdfUtil {
|
|
|
+
|
|
|
+
|
|
|
+ public static void main(String[] args) throws Exception {
|
|
|
+ //Itext4Pdf();
|
|
|
+ long start = System.currentTimeMillis();
|
|
|
+ // createPdf("d:/test.pdf");
|
|
|
+ long end = System.currentTimeMillis();
|
|
|
+ System.out.println(end - start);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static ItextPdfTableVo createTable(String filename, int numColumns, int fontSize) throws Exception {
|
|
|
+ Document document = new Document(PageSize.A4, 0, 0, 50, 0);//SUPPRESS
|
|
|
+ FileOutputStream fos = new FileOutputStream(filename);
|
|
|
+ final PdfWriter writer = PdfWriter.getInstance(document, fos);
|
|
|
+ document.open();
|
|
|
+ // 使用语言包字
|
|
|
+ BaseFont abf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
|
|
|
+ // 外部字体
|
|
|
+ BaseFont fs = BaseFont.createFont("/fonts/msyh.ttc,1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
|
|
|
+ Font tableFont = new Font(fs, fontSize, Font.NORMAL);
|
|
|
+ PdfPTable table = new PdfPTable(numColumns);
|
|
|
+ // 设置各列列宽
|
|
|
+ // table.setTotalWidth(new float[]{90, 100, 100, 120, 100, 100});
|
|
|
+ table.setSpacingBefore(16f);
|
|
|
+ ItextPdfTableVo itextPdfTableVo = new ItextPdfTableVo();
|
|
|
+ itextPdfTableVo.setDocument(document);
|
|
|
+ itextPdfTableVo.setWriter(writer);
|
|
|
+ itextPdfTableVo.setAbf(abf);
|
|
|
+ itextPdfTableVo.setFs(fs);
|
|
|
+ itextPdfTableVo.setTableFont(tableFont);
|
|
|
+ itextPdfTableVo.setTable(table);
|
|
|
+ return itextPdfTableVo;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static PdfPCell createPDFCell(Font tableFont, PdfPTable table, String content, int align, Integer colspan, Integer rowspan) {
|
|
|
+ final PdfPCell cell = cell(tableFont, content, align, colspan, rowspan);
|
|
|
+ table.addCell(cell);
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static PdfPCell createPDFCell(Font tableFont, PdfPTable table, String content, int align, Integer colspan, Integer rowspan, Integer lineSpacing) {
|
|
|
+ final PdfPCell cell = cell(tableFont, content, align, colspan, rowspan, lineSpacing);
|
|
|
+ table.addCell(cell);
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ //底部无边框的单元格
|
|
|
+ public static PdfPCell createPDFCellWithoutBorder(Font tableFont, PdfPTable table, String content, int align, Integer colspan, Integer rowspan) {
|
|
|
+ final PdfPCell cell = cell(tableFont, content, align, colspan, rowspan);
|
|
|
+ cell.setBorder(Rectangle.LEFT | Rectangle.RIGHT);
|
|
|
+ table.addCell(cell);
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PdfPCell cell(Font tableFont, String content, int align, Integer colspan, Integer rowspan) {
|
|
|
+ PdfPCell cell = new PdfPCell(new Phrase(content, tableFont));
|
|
|
+ if (colspan != null && colspan > 0) {
|
|
|
+ cell.setColspan(colspan);
|
|
|
+ }
|
|
|
+ if (rowspan != null && rowspan > 0) {
|
|
|
+ cell.setRowspan(rowspan);
|
|
|
+ }
|
|
|
+ if (PdfPCell.ALIGN_MIDDLE != align) {
|
|
|
+ cell.setHorizontalAlignment(align);
|
|
|
+ cell.setPaddingLeft(8f);
|
|
|
+ cell.setPaddingRight(8f);
|
|
|
+ cell.setPaddingBottom(8f);
|
|
|
+ } else {
|
|
|
+ cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//设置单元格的垂直对齐方式
|
|
|
+ cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
|
|
+ }
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PdfPCell cell(Font tableFont, String content, int align, Integer colspan, Integer rowspan, Integer lineSpacing) {
|
|
|
+ PdfPCell cell = new PdfPCell(new Phrase(content, tableFont));
|
|
|
+ if (colspan != null && colspan > 0) {
|
|
|
+ cell.setColspan(colspan);
|
|
|
+ }
|
|
|
+ if (rowspan != null && rowspan > 0) {
|
|
|
+ cell.setRowspan(rowspan);
|
|
|
+ }
|
|
|
+ cell.setLeading(lineSpacing, 0);
|
|
|
+ if (PdfPCell.ALIGN_MIDDLE != align) {
|
|
|
+ cell.setHorizontalAlignment(align);
|
|
|
+ cell.setPaddingLeft(8f);
|
|
|
+ cell.setPaddingRight(8f);
|
|
|
+ cell.setPaddingBottom(8f);
|
|
|
+ } else {
|
|
|
+ cell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE);//设置单元格的垂直对齐方式
|
|
|
+ cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
|
|
+ }
|
|
|
+ return cell;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成文字类型的水印
|
|
|
+ */
|
|
|
+ public static void createWatermark(Document document, PdfWriter writer, Font waterMarkFont, String content) throws DocumentException, IOException {
|
|
|
+ PdfContentByte waterMarkPdfContent = writer.getDirectContentUnder();
|
|
|
+ Phrase phrase = new Phrase(content, waterMarkFont);
|
|
|
+ float pageWidth = document.right() + document.left();//获取pdf内容正文页面宽度
|
|
|
+ float pageHeight = document.top() + document.bottom();//获取pdf内容正文页面高度
|
|
|
+ //两行三列
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.25f, pageHeight * 0.2f, 45);
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.25f, pageHeight * 0.5f, 45);
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.25f, pageHeight * 0.8f, 45);
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.65f, pageHeight * 0.2f, 45);
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.65f, pageHeight * 0.5f, 45);
|
|
|
+ ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase,
|
|
|
+ pageWidth * 0.65f, pageHeight * 0.8f, 45);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public static void dealHeader(Document document, BaseFont fs, String title, int fontSize) throws DocumentException {
|
|
|
+ //文件title
|
|
|
+ Paragraph p = new Paragraph(title, new Font(fs, fontSize, Font.NORMAL));
|
|
|
+ p.setAlignment(Paragraph.ALIGN_CENTER);
|
|
|
+ // 文件title 段落下空白
|
|
|
+ p.setSpacingAfter(10f);
|
|
|
+ p.setAlignment(Element.ALIGN_CENTER);
|
|
|
+ document.add(p);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void dealEduBody(Document document, PdfPTable table, Font tableFont, Map<String, Object> data) throws Exception {
|
|
|
+ //第一行
|
|
|
+ createPDFCell(tableFont, table, "时间", Element.ALIGN_CENTER, 1, 1);
|
|
|
+ createPDFCell(tableFont, table, data.get("time").toString(), Element.ALIGN_CENTER, 2, 1);
|
|
|
+ createPDFCell(tableFont, table, "地点", Element.ALIGN_CENTER, 1, 1);
|
|
|
+ createPDFCell(tableFont, table, data.get("address").toString(), Element.ALIGN_CENTER, 2, 1);
|
|
|
+ //第二行
|
|
|
+ createPDFCell(tableFont, table, "主持人", Element.ALIGN_CENTER, 1, 1);
|
|
|
+ createPDFCell(tableFont, table, data.get("hostName").toString(), Element.ALIGN_CENTER, 2, 1);
|
|
|
+ createPDFCell(tableFont, table, "记录人", Element.ALIGN_CENTER, 1, 1);
|
|
|
+ createPDFCell(tableFont, table, data.get("recorderName").toString(), Element.ALIGN_CENTER, 2, 1);
|
|
|
+ //内容
|
|
|
+ PdfPCell contentCell = new PdfPCell();
|
|
|
+ contentCell.setColspan(6);
|
|
|
+ Paragraph content = new Paragraph();
|
|
|
+ String text = data.get("content").toString();
|
|
|
+ content.add(new Chunk(text, tableFont));
|
|
|
+ contentCell.addElement(content);
|
|
|
+ contentCell.setBorder(Rectangle.LEFT | Rectangle.RIGHT);
|
|
|
+ table.addCell(contentCell);
|
|
|
+
|
|
|
+ //总结
|
|
|
+ PdfPCell noteCell = new PdfPCell();
|
|
|
+ noteCell.setColspan(6);
|
|
|
+ Paragraph paragraph = new Paragraph();
|
|
|
+ String noteText = data.get("note").toString();
|
|
|
+ paragraph.add(new Chunk(noteText, tableFont));
|
|
|
+ noteCell.addElement(paragraph);
|
|
|
+ noteCell.setBorder(Rectangle.LEFT | Rectangle.RIGHT);
|
|
|
+ table.addCell(noteCell);
|
|
|
+ //图片填充
|
|
|
+ final PdfPTable imageTable = getImage((List<String>) data.get("image"), 12);
|
|
|
+ final PdfPCell cell = new PdfPCell();
|
|
|
+ cell.setNoWrap(false);
|
|
|
+ cell.setPaddingLeft(8f);
|
|
|
+ cell.setPaddingRight(8f);
|
|
|
+ cell.setPaddingBottom(8f);
|
|
|
+ cell.setPaddingTop(8f);
|
|
|
+ cell.setColspan(6);
|
|
|
+ cell.setBorder(Rectangle.LEFT | Rectangle.RIGHT | Rectangle.BOTTOM);
|
|
|
+ cell.addElement(imageTable);
|
|
|
+ table.addCell(cell);
|
|
|
+
|
|
|
+ //第三行
|
|
|
+ createPDFCell(tableFont, table, "参会人员签字", Element.ALIGN_CENTER, 1, 1);
|
|
|
+ createPDFCell(tableFont, table, data.get("users").toString(), Element.ALIGN_CENTER, 5, 1);
|
|
|
+
|
|
|
+ document.add(table);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static PdfPTable getImage(List<String> images, int totalImages) throws Exception {
|
|
|
+ if (images == null) {
|
|
|
+ images = new ArrayList<>();
|
|
|
+ }
|
|
|
+ PdfPTable innerTable = new PdfPTable(3);
|
|
|
+ /*for (int i = 0; i < 7; i++) {
|
|
|
+ //模拟数据
|
|
|
+ images.add("1.jpg");
|
|
|
+ }*/
|
|
|
+ //这里根据实际图片数量来判断是否需要补充白色图片,保证每行显示3张图片,用以填充空白
|
|
|
+ final int reallySize = images.size();
|
|
|
+ //此处重新new对象, JPA会自动将images的更新持久化到数据,导致数据出错
|
|
|
+ List<String> list = new ArrayList<>(images);
|
|
|
+ for (int i = 0; i < totalImages - reallySize && totalImages > reallySize; i++) {
|
|
|
+ ClassPathResource resource = new ClassPathResource("file" + File.separator + "black.png");
|
|
|
+ String path = resource.getPath();
|
|
|
+ list.add(path);
|
|
|
+ }
|
|
|
+ //分割,每行显示3张图片,获取分割的行数
|
|
|
+ List<List<String>> rows = new ArrayList<>();
|
|
|
+ for (int i = 0; i < list.size(); i += 3) {
|
|
|
+ List<String> row = list.subList(i, Math.min(i + 3, list.size()));
|
|
|
+ rows.add(row);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (List<String> row : rows) {
|
|
|
+ for (String image : row) {
|
|
|
+ Image imageData = null;
|
|
|
+ if (image.contains("black.png")) {
|
|
|
+ imageData = Image.getInstance(image);
|
|
|
+ //判断意外情况,比如环境中不存在该图片,则跳过
|
|
|
+ if (imageData == null) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ byte[] bytes = convertFileToByteArray(new File(image));
|
|
|
+ imageData = Image.getInstance(bytes);
|
|
|
+ }
|
|
|
+ imageData.scaleAbsolute(100, 100);
|
|
|
+ PdfPCell cell = new PdfPCell(Image.getInstance(imageData));
|
|
|
+ cell.setBorder(Rectangle.NO_BORDER);
|
|
|
+ cell.setHorizontalAlignment(Element.ALIGN_CENTER);
|
|
|
+ cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
|
|
|
+ innerTable.addCell(cell);
|
|
|
+ }
|
|
|
+ //实际上这儿永远不会存在不满足3个的情况,因为上面会根据图片数量补全到十二个
|
|
|
+ //具体补全数量可以根据实际图片大小与页面尺寸来调整
|
|
|
+ int size = row.size();
|
|
|
+ while (size < 3) {
|
|
|
+ PdfPCell emptyCell = new PdfPCell();
|
|
|
+ emptyCell.setBorder(Rectangle.NO_BORDER);
|
|
|
+ innerTable.addCell(emptyCell);
|
|
|
+ size++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ PdfPTable outerTable = new PdfPTable(1);
|
|
|
+ PdfPCell innerCell = new PdfPCell(innerTable);
|
|
|
+ innerCell.setBorder(Rectangle.NO_BORDER);
|
|
|
+ outerTable.addCell(innerCell);
|
|
|
+ return outerTable;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static byte[] convertFileToByteArray(File file) throws IOException {
|
|
|
+ FileInputStream fis = new FileInputStream(file);
|
|
|
+ byte[] byteArray = new byte[(int) file.length()];
|
|
|
+ fis.read(byteArray);
|
|
|
+ fis.close();
|
|
|
+ return byteArray;
|
|
|
+ }
|
|
|
+}
|