利用反射导出简单pdf报表和excel
leader给了导出pdf的需求,给了我示例代码,但我发现是硬编码的形式极大的影响了开发的效率。
然后我思考了一下,它就是将实体对象的属性按顺序赋值,那我为何不用反射获取所有属性进行遍历赋值呢。所以我为此封装了pdf导出的工具类,只需传入数据,标题就可以导出了,不需要大量的硬编码。代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | /** * * @param response * @param records 数据List * @param reportTitleList 标题List * @param titleName 标题名称 * @throws DocumentException * @throws IOException * @throws NoSuchFieldException * @throws IllegalAccessException */ public static void getPdfReport(HttpServletResponse response, List<?> records, List<String> reportTitleList,String titleName) throws DocumentException, IOException, IllegalAccessException { //设置纸张 Rectangle rect = new Rectangle(PageSize.A4); //设置底色 rect.setBackgroundColor(BaseColor.WHITE); //创建文档实例 Document document = new Document(rect); String fileName = new Date().getTime() + ".pdf" ; ByteArrayOutputStream baos = new ByteArrayOutputStream( 1024 ); //创建输出流 PdfWriter writer = PdfWriter.getInstance(document, baos); //添加中文字体 BaseFont bf = BaseFont.createFont( "STSong-Light" , "UniGB-UCS2-H" , BaseFont.NOT_EMBEDDED); //设置字体样式 Font firsetTitleFont = new Font(bf, 12 , Font.NORMAL); //标题 Font textFont = new Font(bf, 10 , Font.NORMAL); //正常 //设置页脚 PdfReportM1HeaderFooter footer = new PdfReportM1HeaderFooter(); writer.setPageEvent(footer); //----------------------------------以上最好都写在document.open()前----------------------------------------- //文件开始 document.open(); //创建文件新页面(第1页) document.newPage(); //创建标题长度列表格 PdfPTable pt = new PdfPTable(reportTitleList.size()); pt.setTotalWidth( 550 ); //设置总宽度 pt.setLockedWidth( true ); int [] sizeList= new int [reportTitleList.size()]; int length =reportTitleList.size(); for ( int i = 0 ; i < length; i++) { sizeList[i]= 1 ; } pt.setWidths(sizeList); pt.setSpacingBefore( 30 ); //设置表格上面空白 pt.setSpacingAfter( 30 ); //设置表格下面空白 //创建cell PdfPCell cell = new PdfPCell(); cell.setBorder( 0 ); //设置无边框 Paragraph paragraph = new Paragraph( 10 ); // 边距 // 1 2 3 中右左 paragraph.setAlignment( 1 ); // 对齐方式 Chunk chunk = new Chunk(titleName,firsetTitleFont); paragraph.add(chunk); document.add(paragraph); //列标题 for ( int i = 0 ; i < reportTitleList.size(); i++) { cell = new PdfPCell(); cell.setUseAscender( true ); Paragraph elements = new Paragraph(reportTitleList.get(i), firsetTitleFont); elements.setAlignment( 1 ); cell.addElement(elements); cell.setHorizontalAlignment(Element.ALIGN_CENTER); //设置水平居中 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中 pt.addCell(cell); } //pdf内容 for (Object record : records) { //List里的对象 Field[] declaredFields = record.getClass().getDeclaredFields(); //对象里的参数数组 for (Field field : declaredFields) { field.setAccessible( true ); cell = new PdfPCell(); cell.setUseAscender( true ); Paragraph area = new Paragraph(String.valueOf(field.get(record)), textFont); area.setAlignment( 1 ); cell.addElement(area); cell.setHorizontalAlignment(Element.ALIGN_CENTER); //设置水平居中 cell.setVerticalAlignment(Element.ALIGN_MIDDLE); //设置垂直居中 pt.addCell(cell); } } document.add(pt); //文件关闭 document.close(); response.setCharacterEncoding( "UTF-8" ); response.setContentLength(baos.size()); response.setHeader( "Content-type" , "application/pdf;charset=utf-8" ); response.addHeader( "Content-Disposition" , "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8" )); ServletOutputStream outputStream = response.getOutputStream(); outputStream.write(baos.toByteArray(), 0 , baos.size()); outputStream.flush(); outputStream.close(); } |
这个工具类在大量报表导出时,我多次能用到,节省了大量的开发时间,也增强了接口阅读性。
后面我也将同事们写的导出excel的接口重构了一下,将excel导出封装成工具类,只需要在实体类上加入@excel注解即可。切忌硬编码编写代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | /*** * * @param response * @param VOClass 报表VO对象 * @param excelList 报表vo对象数据list * @param titleName excel标题名字 * @throws UnsupportedEncodingException */ public static void getExcel(HttpServletResponse response, Class<?> VOClass, List<?> excelList, String titleName) throws UnsupportedEncodingException { //三个参数,导出标题名,sheetname,文件格式 HSSF:xsl XSSH:xslx ExportParams params = new ExportParams(titleName, titleName, ExcelType.HSSF); Workbook workbook = ExcelExportUtil.exportExcel(params, VOClass, excelList); //以流的形式导出 ServletOutputStream outputStream = null ; String fileName = titleName + ".xls" ; //创建文件名 String fileNameURL = URLEncoder.encode(fileName, "UTF-8" ); //防止中文乱码 try { //流形式 response.setHeader( "content-type" , "application/octet-stream" ); response.setHeader( "content-disposition" , "attachment;filename=" + fileNameURL+ ";" + "filename*=utf-8''" +fileNameURL); outputStream = response.getOutputStream(); workbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); } finally { if ( null != outputStream){ try { outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通