依赖
implementation 'com.itextpdf:itextpdf:5.5.13.3'implementation 'com.itextpdf:itext-asian:5.2.0'implementation 'com.alibaba:fastjson:1.2.83'compileOnly 'org.projectlombok:lombok:1.18.22'annotationProcessor "org.projectlombok:lombok:1.18.22"
测试
import com.alibaba.fastjson.JSON;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import java.util.List;
import java.util.Map;public class GeneratePdfReport {private static final Logger logger = LoggerFactory.getLogger(GeneratePdfReport.class);public static void main(String[] args) {FontFactory.registerDirectories();// drawTable();drawRowspan0();}public static ByteArrayInputStream citiesReport(List<City> cities) {Document document = new Document();ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();try {// 建立一个书写器(内存流方式)PdfWriter.getInstance(document, byteArrayOutputStream);document.open();PdfPTable table = new PdfPTable(3);table.setWidthPercentage(60);table.setWidths(new int[]{1, 3, 3});Font headFont = FontFactory.getFont(FontFactory.HELVETICA_BOLD);PdfPCell h_cell;h_cell = new PdfPCell(new Phrase("Id", headFont));h_cell.setHorizontalAlignment(Element.ALIGN_CENTER);// LeadingParagraph paragraph = new Paragraph();paragraph.setLeading(2.5f);table.addCell(h_cell);h_cell = new PdfPCell(new Phrase("Name", headFont));h_cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(h_cell);h_cell = new PdfPCell(new Phrase("Population", headFont));h_cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(h_cell);for (City city : cities) {PdfPCell cell;cell = new PdfPCell(new Phrase(city.getId().toString()));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_CENTER);table.addCell(cell);cell = new PdfPCell(new Phrase(city.getName()));cell.setPaddingLeft(5);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_LEFT);table.addCell(cell);cell = new PdfPCell(new Phrase(String.valueOf(city.getPopulation())));cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_RIGHT);cell.setPaddingRight(5);table.addCell(cell);}document.add(table);} catch (DocumentException ex) {logger.error("Error occurred: {0}", ex);} finally {document.close();}return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());}@SneakyThrowsprivate static void drawTable() {String[] headers = {"列一", "列二", "列三", "列四", "列五", "列六"};String list = "[{\"balance\":\"42402\",\"changeDate\":\"20211026111641\",\"dgst\":\"SSTR\",\"outMoney\":\"0\",\"bankSeqNo\":\"00000000000641199893\",\"inMoney\":\"11539\"},{\"balance\":\"30863\",\"changeDate\":\"20211005133736\",\"dgst\":\"SALE\",\"outMoney\":\"7500\",\"bankSeqNo\":\"00000000000635138192\",\"inMoney\":\"0\"},{\"balance\":\"38363\",\"changeDate\":\"20210926113940\",\"dgst\":\"SSTR\",\"outMoney\":\"0\",\"bankSeqNo\":\"00000000000632420138\",\"inMoney\":\"11539\"},{\"balance\":\"26824\",\"changeDate\":\"20210925111144\",\"dgst\":\"SALE\",\"outMoney\":\"11150\",\"bankSeqNo\":\"00000000000632752221\",\"inMoney\":\"0\"},{\"balance\":\"37974\",\"changeDate\":\"20210922083109\",\"dgst\":\"SALE\",\"outMoney\":\"4860\",\"bankSeqNo\":\"00000000000631851353\",\"inMoney\":\"0\"},{\"balance\":\"42834\",\"changeDate\":\"20210919153251\",\"dgst\":\"SALE\",\"outMoney\":\"7910\",\"bankSeqNo\":\"00000000000631503750\",\"inMoney\":\"0\"},{\"balance\":\"50744\",\"changeDate\":\"20210917080014\",\"dgst\":\"SALE\",\"outMoney\":\"5870\",\"bankSeqNo\":\"00000000000630377865\",\"inMoney\":\"0\"},{\"balance\":\"56614\",\"changeDate\":\"20210915153430\",\"dgst\":\"SALE\",\"outMoney\":\"8560\",\"bankSeqNo\":\"00000000000630120441\",\"inMoney\":\"0\"},{\"balance\":\"65174\",\"changeDate\":\"20210830103432\",\"dgst\":\"SALE\",\"outMoney\":\"6200\",\"bankSeqNo\":\"00000000000625635279\",\"inMoney\":\"0\"},{\"balance\":\"71374\",\"changeDate\":\"20210825124135\",\"dgst\":\"SSTR\",\"outMoney\":\"0\",\"bankSeqNo\":\"00000000000624479550\",\"inMoney\":\"11539\"}]";List<Map<String, Object>> mapList = (List) JSON.parseArray(list);ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();PdfWriter writer = null;Document document = null;try {// 创建纵向文件{// 生成pdfdocument = new Document();// 页面大小Rectangle rectangle;{rectangle = new Rectangle(PageSize.A4);// 页面背景颜色rectangle.setBackgroundColor(BaseColor.WHITE);}document.setPageSize(rectangle);// 页边距 左,右,上,下document.setMargins(20, 40, 40, 20);}// 建立一个书写器(内存流方式)PdfWriter.getInstance(document, byteArrayOutputStream);// 打开文件document.open();// 添加字体样式Font bigFont, blueFont;{BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);bigFont = new Font(bf, 14, Font.NORMAL, BaseColor.BLACK);blueFont = new Font(bf, 10, Font.NORMAL, BaseColor.BLACK);}// 段落内容Paragraph title;{title = new Paragraph("测试pdf", bigFont);title.setSpacingBefore(5);title.setSpacingAfter(5);// 文字居中显示title.setAlignment(Element.ALIGN_CENTER);}// 添加段落内容document.add(title);// 创建表格列数PdfPTable table;{table = new PdfPTable(headers.length);// 宽度100%填充table.setWidthPercentage(100);}// 创建表头{for (String header_text : headers) {PdfPCell cell;{cell = new PdfPCell(new Paragraph(header_text, bigFont));cell.setFixedHeight(27f);// 默认不跨行、跨列cell.setRowspan(1);cell.setColspan(1);// 居中显示cell.setHorizontalAlignment(Element.ALIGN_CENTER);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);// 设置边框cell.setBorder(Rectangle.RIGHT + Rectangle.BOTTOM);cell.setPadding(5);}table.addCell(cell);}}// document.add(table); // mark// 填充数据for (Map<String, Object> map : mapList) {// 获取对象// Map 获取key & valuefor (Map.Entry<String, Object> entry : map.entrySet()) {Object value = entry.getValue();PdfPCell cell;{cell = new PdfPCell(new Paragraph(value.toString(), blueFont));cell.setFixedHeight(27f);// 默认不跨行、跨列 ps: 0 or 1 没有区别cell.setRowspan(1);cell.setColspan(1);cell.setVerticalAlignment(Element.ALIGN_MIDDLE);cell.setHorizontalAlignment(Element.ALIGN_LEFT);// 设置边框cell.setBorder(Rectangle.LEFT);// cell.setBorderWidthRight(1f);cell.setPadding(5);}table.addCell(cell);}// document.add(table); // mark}document.add(table); // mark} catch (DocumentException | IOException ignored) {} finally {if (document != null) {// 关闭文档document.close();}if (writer != null) {// 关闭书写器writer.close();}}Base64.Encoder encoder = Base64.getEncoder();String url = "data:application/pdf;base64," + encoder.encodeToString(byteArrayOutputStream.toByteArray());System.out.println(url);}@SneakyThrowspublic static void drawRowspan0() {ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();Document document = new Document();PdfWriter.getInstance(document, byteArrayOutputStream);document.open();PdfPTable table = new PdfPTable(3); // 创建一个三列的表格for (int i = 0; i < 5; i++) {PdfPCell cell = new PdfPCell();cell.addElement(new com.itextpdf.text.Paragraph("Cell 1"));if (i == 2)cell.setRowspan(2); // 第三个单元格不跨行// else// cell.setRowspan(2);table.addCell(cell);}document.add(table);document.close();Base64.Encoder encoder = Base64.getEncoder();String url = "data:application/pdf;base64," + encoder.encodeToString(byteArrayOutputStream.toByteArray());System.out.println(url);}}
- 添加图层
// 引入itextpdf库X
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;// 打开PDF文件
PdfReader reader = new PdfReader("input.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf"));// 创建图层对象
PdfLayer layer = new PdfLayer("New Layer", stamper.getWriter());// 添加内容到图层
layer.setOn(true);// 将图层添加到PDF文件
stamper.addAnnotation(layer);
stamper.close();
// 引入itextpdf库X
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;// 打开PDF文件
PdfReader reader = new PdfReader("input.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("output.pdf"));// 创建图层对象
PdfLayer layer = new PdfLayer("New Layer", stamper.getWriter());// 添加内容到图层
layer.setOn(true);// 将图层添加到PDF文件
stamper.addAnnotation(layer);
stamper.close();
(以下内容忽略)
jdk 运行 js
import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.FileNotFoundException;
import java.io.FileReader;class JavascriptUtils {public static void runDisplay() {ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");try {// REPL read eval print loopengine.eval(new FileReader("test.js"));Invocable invocable = (Invocable) engine;Object result;result = invocable.invokeFunction("addNumber", 1, 2);System.out.println(engine);System.out.println(result);System.out.println(result.getClass());} catch (FileNotFoundException | NoSuchMethodException | ScriptException e) {e.printStackTrace();}}public static void main(String[] args) {runDisplay();}
}
- 事件监听
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class EventDemo {@Beanpublic MyListener myListener() {// 使用注入进行注册{监听器} 来响应其他{自定义事件}return new MyListener();}public static void main(String[] args) {// 在 Spring 中,事件发布和监听器注册都是通过 ApplicationContext 来实现的AnnotationConfigApplicationContext context =new AnnotationConfigApplicationContext(EventDemo.class);context.publishEvent(new MyEvent("hello world"));// Spring 内置了很多事件,例如:ContextStartedEvent,ContextStoppedEvent,// ContextRefreshedEvent,ContextClosedEvent (应用程序的不同生命周期阶段)// RequestHandledEvent (Web 请求处理过程) 等}private static class MyEvent extends ApplicationEvent {private final String message;public MyEvent(String message) {super(message);this.message = message;}public String getMessage() {return message;}}// (need inject)private static class MyListener implements ApplicationListener<MyEvent> {@Overridepublic void onApplicationEvent(MyEvent event) {System.out.println("Received event: " + event.getMessage());}}
}