利用反射导出简单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();
                }
            }
        }
    }

  

posted @   古家杰  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示