重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章给大家分享的是有关Java使用itext5实现PDF表格文档导出的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。
专注于为中小企业提供网站设计制作、成都网站建设服务,电脑端+手机端+微信端的三站合一,更高效的管理,为中小企业岱岳免费做网站提供优质的服务。我们立足成都,凝聚了一批互联网行业人才,有力地推动了上1000+企业的稳健成长,帮助中小企业通过网站建设实现规模扩充和转变。
最近拿到一个需求,需要导出PDF文档,市面上可以实现的方法有很多,经过测试和调研决定使用itext5来实现,话不多说,说干就干。
1.依赖导入
com.itextpdf itextpdf 5.5.13.1 com.itextpdf itext-asian 5.2.0
这里说明下:上面的依赖就是主要实现PDF生成的,下面的依赖是中文字体相关依赖;
2.PDF表格导出实现
1.导出PDF
// 1.打开文档并设置基本属性 Document document = new Document(); // 2.设置请求头,encode文件名 response.setContentType("application/pdf;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode("" + recordDto.getTitle() + ".pdf", "UTF-8")); // 3.通过流将pdf实例写出到浏览器 PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
至此导出PDF已经实现了,只是这个PDF中什么内容都没有,明白这一点,接下来做的就是给这个文档“加料”咯(这里的response就是HttpServletResponse)。
2.页面美化
// 这里的wirter就是上文的writer writer.setViewerPreferences(PdfWriter.PageModeUseThumbs); writer.setPageSize(PageSize.A4);
这里设置了文档的显示缩略图以及文档大小为A4;
3.中文字体设置
public static Font getPdfChineseFont() throws Exception { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); fontChinese.setColor(BaseColor.BLACK); fontChinese.setSize(11); return fontChinese; }
这个方法设置了中文字体样式,感兴趣的同学可以试试其他的样式,例如:字体颜色,大小,字体都可以修改;
4.输出表格内容到文档
// 首先打开文档 document.open(); // 向文档中添加表格数据 private static void printBasicInfo(ShopApplyRecordDto recordDto, Document document, Font font) throws DocumentException { // 表格中的数据 Object[][] basicDatas = { {"标题","xxx申请", "审批编号","1234"}, {"申请人","小明", "申请商铺","xxx商场"}, {"申请日期","2020/1/16", "审批结果","同意")}}; // 每个cell的宽度 float[] widthss = {50, 200, 50, 200}; // 创建一个表格,每一行有四个cell PdfPTable basicTable = new PdfPTable(widthss); // 外层循环表格的行 for (int i = 0; i < basicDatas.length; i++) { // 内层循环每一行具体数据 for (int j = 0; j < basicDatas[i].length; j++) { // 新建一个cell PdfPCell cell = new PdfPCell(); // 这个方法是统一设置表格和cell的样式,下面会写 setTableStyle(basicTable, cell); // cell中需要填充数据的格式 Paragraph paragraph = new Paragraph(StrUtil.toString(basicDatas[i][j]), font); // 设置cell的值 cell.setPhrase(paragraph); // 将cell添加到表格中 basicTable.addCell(cell); } } // 将表格添加到文档中 document.add(basicTable); } // 结束时要关闭文档 document.close();
大功告成,现在导出的PDF中已经有了类似这样的表格了:
当然你的样式会很丑,接下来我们来设置下样式。
5.表格和cell样式设置
public static void setTableStyle(PdfPTable table, PdfPCell cell) { // 设置表格样式 table.setLockedWidth(true); table.setTotalWidth(500); table.setHorizontalAlignment(Element.ALIGN_LEFT); // 设置单元格样式 cell.setMinimumHeight(35); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); cell.setBackgroundColor(BaseColor.WHITE); cell.setBorder(0); cell.setBorderWidthTop(0.1f); cell.setBorderWidthBottom(0.1f); cell.setBorderWidthLeft(0.1f); cell.setBorderWidthRight(0.1f); cell.setBorderColorBottom(BaseColor.BLACK); cell.setBorderColorLeft(BaseColor.BLACK); cell.setBorderColorRight(BaseColor.BLACK); cell.setBorderColorTop(BaseColor.BLACK); cell.setPadding(3); }
api方法还是比较易懂的,这里就不多赘述了,不明白的自己设置试试就可以做出自己喜欢的样式咯。
6.页眉和页码的设置
这里说明下,itext2和itext5的api有很大不同,2的版本有一个专门的HeaderFooter类来设置样式,5的版本没有这样的类,取而代之的是PdfPageEventHelper这样一个事件处理类,这里大家千万别弄混了,这两个版本的api互相不兼容;
这里首先写一个PdfPageEventHelper的子类来实现页眉页码的打印:
public class HeaderFooter extends PdfPageEventHelper { // 这里是业务相关的属性可以无视 private ShopApplyRecordDto recordDto; private SysUserInfo userInfo; // 大部分情况下页眉的值是动态的,这里可以在初始化的时候进行参数传递 public HeaderFooter(ShopApplyRecordDto recordDto, SysUserInfo userInfo) { this.recordDto = recordDto; this.userInfo = userInfo; } public HeaderFooter() { } public ShopApplyRecordDto getRecordDto() { return recordDto; } public void setRecordDto(ShopApplyRecordDto recordDto) { this.recordDto = recordDto; } public SysUserInfo getUserInfo() { return userInfo; } public void setUserInfo(SysUserInfo userInfo) { this.userInfo = userInfo; } // 这个方法就是实现页眉和页码的关键:它的含义是每当页面结束会执行该方法 @Override public void onEndPage(PdfWriter writer, Document document) { Font font = null; try { font = getPdfChineseFont(); } catch (Exception e) { e.printStackTrace(); } SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd HH:mm"); // 设置页眉:这里图省事就用空格来实现左中右三个位置的页眉,其实可以写三个,通过Element.ALIGN_LEFT来控制页眉的位置,document.left()/document.top()这两个可以设置页眉具体位置类似于html的上下调整,大家可以多试试 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_LEFT, new Phrase("所属项目:" + recordDto.getMallName() + " 打印时间:" + format.format(new Date()) + " 打印人:" + userInfo.getUserName(), font), document.left(), document.top() + 3, 0); // 获得一个名为“art”的盒子 Rectangle rect = writer.getBoxSize("art"); // 设置页码:这里的页码位置已经设置好,大家可直接使用,至于1/20这种效果的页码实现则十分复杂,如有需求请自行百度/谷歌 ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(String.format("%d", writer.getPageNumber())), (rect.getLeft() + rect.getRight()) / 2, rect.getBottom() - 18, 0); } public static Font getPdfChineseFont() throws Exception { BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font fontChinese = new Font(bfChinese, 12, Font.NORMAL); fontChinese.setColor(BaseColor.BLACK); fontChinese.setSize(11); return fontChinese; } } 接下来就很简单了,将我们的HeaderFooter设置给PdfWriter对象即可: // 新建HeaderFooter并传递需要的参数 HeaderFooter headerFooter = new HeaderFooter(recordDto, userInfo); // 新建一个盒子 Rectangle rect = new Rectangle(36, 54, 559, 788); // 设置名称为“art”,上面get的就是这个盒子了 writer.setBoxSize("art", rect); writer.setPageEvent(headerFooter); // 这个可以设置内容的margin document.setMargins(45f, 45f, 65f, 50f);
7.效果展示
感谢各位的阅读!关于“Java使用itext5实现PDF表格文档导出的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!