先简单介绍一下IText
iText是一种生成PDF报表的Java组件。通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,这样就很好的解决了B/S系统的报表处理问题。
IText生成PDF报表的方式
用Itext自己布局加元素生成pdf //itext-PdfStamper pdfStamper(俗称抠模板)
读取pdf模板进行填充 //itext-Document document(正常代码撰写)
两种方式各有优缺, pdfStamper代码简单,但是模板要先提供,且字段长度固定、不灵活. document模板可根据代码调整,缺点是要维护的后台代码较多,接下来分别演示一下
首先引入maven坐标
<dependency> <groupId>com.itextpdfgroupId> <artifactId>itextpdfartifactId> <version>5.5.13.1version> dependency> <dependency> <groupId>com.itextpdfgroupId> <artifactId>itext-asianartifactId> <version>5.2.0version> <dependency>
2.演示通过模板填充数据,首先新建一个word文档,编辑好文档内容,留出需要填充的留白
然后转换成pdf,在Adobe Acrobat中编辑表单域,填充留白,类似于操作word文档的占位符
接下来完成一个简单的小demo,上面已经将坐标导入
@GetMapping("/pdfTemplate") public void pdfTemplate(HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException { //为了显示方便,直接在浏览器预览 response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline;"); PdfReader pdfReader = new PdfReader("D:\\WordFile\\demo.pdf"); PdfStamper ps = new PdfStamper(pdfReader, response.getOutputStream()); AcroFields fields = ps.getAcroFields(); //使用中文字体 BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); ArrayList<BaseFont> fontList = new ArrayList<BaseFont>(); fontList.add(bf); fields.setSubstitutionFonts(fontList); HashMap<String, String> map = new HashMap<>(); map.put("id","1254"); map.put("username","张学良"); map.put("gender","男"); map.put("address","沈阳"); map.put("birthday",TimeTool.dateToStr(new Date(),null)); map.put("idnumber","123456789"); for (String key : map.keySet()) { fields.setField(key,map.get(key)); } //必须要调用这个,否则文档不会生成的 ps.setFormFlattening(true); ps.close(); }
3.启动项目,浏览器进行测试,效果如图
4.接下来演示通过代码直接生成pdf报表,不借助模板
由于要通过代码布局,所以我事先定义了全局的字体静态变量
// 定义全局的字体静态变量 private static Font titlefont; private static Font headfont; private static Font keyfont; private static Font textfont; // 最大宽度 private static int maxWidth = 520; // 静态代码块 static { try { // 不同字体(这里定义为同一种字体:包含不同字号、不同style) BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); titlefont = new Font(bfChinese, 16, Font.BOLD); headfont = new Font(bfChinese, 14, Font.BOLD); keyfont = new Font(bfChinese, 10, Font.BOLD); textfont = new Font(bfChinese, 10, Font.NORMAL); } catch (Exception e) { e.printStackTrace(); } }
来一个简单的需求吧,将数据库的一张表的所有信息打印到pdf报表
直接贴代码吧
// 定义全局的字体静态变量 private static Font titlefont; private static Font headfont; private static Font keyfont; private static Font textfont; // 最大宽度 private static int maxWidth = 520; // 静态代码块 static { try { // 不同字体(这里定义为同一种字体:包含不同字号、不同style) BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); titlefont = new Font(bfChinese, 16, Font.BOLD); headfont = new Font(bfChinese, 14, Font.BOLD); keyfont = new Font(bfChinese, 10, Font.BOLD); textfont = new Font(bfChinese, 10, Font.NORMAL); } catch (Exception e) { e.printStackTrace(); } } @Autowired(required = false) SysUserMapper sysUserMapper; @GetMapping("/createPdf") public void createPdf(HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException, IllegalAccessException { response.setContentType("application/pdf"); response.setHeader("Content-Disposition", "inline;"); // 新建一个文档,默认是A4纸的大小,4个边框为36 Document document = new Document(PageSize.A4); // 将文档输出,我们写到输出流里面 PdfWriter instance = PdfWriter.getInstance(document, response.getOutputStream()); // 打开文档 document.open(); // 段落 Paragraph paragraph = new Paragraph("用户登记表", titlefont); paragraph.setAlignment(1); //设置文字居中 0靠左 1,居中 2,靠右 paragraph.setIndentationLeft(12); //设置左缩进 paragraph.setIndentationRight(12); //设置右缩进 paragraph.setFirstLineIndent(24); //设置首行缩进 paragraph.setLeading(20f); //行间距 paragraph.setSpacingBefore(5f); //设置段落上空白 paragraph.setSpacingAfter(10f); //设置段落下空白 // 写入数据 document.add(paragraph); Paragraph elements = new Paragraph("打印时间:" + TimeTool.dateToStr(new Date(), null),textfont); elements.setSpacingAfter(10f); elements.setAlignment(2); document.add(elements); List<UserEntity> userEntities = sysUserMapper.selectList(null); PdfPTable pdfTable = new PdfPTable(6); //设置表格占PDF文档100%宽度 pdfTable.setWidthPercentage(100); //水平方向表格控件对齐 pdfTable.setHorizontalAlignment(PdfPTable.ALIGN_CENTER); //创建一个表格的表头单元格 PdfPCell pdfTableHeaderCell = new PdfPCell(); pdfTableHeaderCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); UserEntity userEntity1 = new UserEntity(); for (Field field : userEntity1.getClass().getDeclaredFields()) { pdfTableHeaderCell.setPhrase(new Paragraph(field.getName(),textfont)); pdfTable.addCell(pdfTableHeaderCell); pdfTableHeaderCell.setMinimumHeight(30); } //创建一个表格的正文内容单元格 PdfPCell pdfTableContentCell = new PdfPCell(); //设置水平对齐方式 pdfTableContentCell.setHorizontalAlignment(PdfPCell.ALIGN_CENTER); //设置垂直居中 pdfTableContentCell.setVerticalAlignment(PdfPCell.ALIGN_MIDDLE); //表格内容行数的填充 for (UserEntity userEntity : userEntities) { Class extends UserEntity> aClass = userEntity.getClass(); Field[] fields = aClass.getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); pdfTableContentCell.setPhrase(new Paragraph((String) field.get(userEntity), textfont)); pdfTable.addCell(pdfTableContentCell); } } document.add(pdfTable); // 关闭文档 document.close(); }
生成效果如图
先到这吧...