导出为PDF系列(二)__java后台动态生成PDF内容

接到一个需求,要求动态生成一个excel,其中表头要是动态生成的(表头字段不确定)。

Talk is cheap,let me show the code.

 @RequestMapping(value={"/exportPdfDynamic"})
    public String exportPdfDynamic(HttpServletResponse response) throws UnsupportedEncodingException{
        OutputStream os = null;
        PdfStamper ps = null;
        PdfReader reader = null;
        try {
            List<User> users = new ArrayList<>();
            
            User user1 = new User();
            user1.setId("111");
            user1.setUsername("小花");
            user1.setSex("女");
            user1.setPassword("secret");
            users.add(user1);
            User user2 = new User();
            user2.setId("222");
            user2.setUsername("小明");
            user2.setSex("");
            user2.setPassword("secret");
            users.add(user2);
            
            String filename="user_info.pdf";
            //数据填充到PDF
            String filePath = generatePDFs(users,filename);
            //将生成的PDF展示到浏览器下载
            System.setProperty("javax.xml.parsers.DocumentBuilderFactory",
                    "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl");
            String path = this.getClass().getClassLoader().getResource("PDF/"+filename).getPath();

            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(filename, "UTF-8"));
            os = response.getOutputStream();
            reader = new PdfReader(path);
            ps = new PdfStamper(reader, os);
            ps.setFormFlattening(true);
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                ps.close();
                reader.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
    com.lowagie.text.Document document = new com.lowagie.text.Document();// 建立一个Document对象

    private static com.lowagie.text.Font headfont;// 设置字体大小
    private static com.lowagie.text.Font keyfont;// 设置字体大小
    private static com.lowagie.text.Font textfont;// 设置字体大小
    static {
        //中文格式
        com.lowagie.text.pdf.BaseFont bfChinese;
        try {
            // 设置中文显示

            bfChinese = com.lowagie.text.pdf.BaseFont.createFont("C:/WINDOWS/Fonts/SIMSUN.TTC,1", com.itextpdf.text.pdf.BaseFont.IDENTITY_H, com.itextpdf.text.pdf.BaseFont.EMBEDDED);
            headfont = new com.lowagie.text.Font(bfChinese, 14, com.lowagie.text.Font.BOLD);// 设置字体大小
            keyfont = new com.lowagie.text.Font(bfChinese, 6, com.lowagie.text.Font.BOLD);// 设置字体大小
            textfont = new com.lowagie.text.Font(bfChinese, 6, com.lowagie.text.Font.NORMAL);// 设置字体大小
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private String generatePDFs(List<User> list,String filename){
        String saveFilePathAndName = "";
        try{

            String root = this.getClass().getClassLoader().getResource("/").getPath();
            File file = new File(root+"PDF/"+filename);
            if (!new File(root+"PDF").exists()){
                new File(root+"PDF").mkdir();
            }
            file.createNewFile();

            document.setPageSize(com.lowagie.text.PageSize.A4);// 设置页面大小
            com.lowagie.text.pdf.PdfWriter.getInstance(document, new FileOutputStream(file));
            document.open();

            file.createNewFile();  //生成一个pdf文件
            //确定表头字段
            String[] head = {};
            String[] headForBody = {};
            if (null != list && list.size() > 0) {
                //确定表头字段
                Field[] field = User.class.getDeclaredFields();
                try {
                    Set<String> hashSet = new HashSet<String>();
                    SimpleDateFormat sdf = null;
                    sdf= new SimpleDateFormat("MM/dd/yyyy");
                    for (int i = 0; i < list.size(); i++) {
                        User user = list.get(i);
                        //取表头
                        dealVoForHead(user);

                        //设置日期格式
                        if(user.getPassportIssueDate() != null){
                            user.setPassportIssueDate(sdf.format(new Date(Long.valueOf(user.getPassportIssueDate()))));
                        }

                        for(int j=0 ; j<field.length ; j++){//遍历所有属性
                            PropertyDescriptor pd = new PropertyDescriptor(field[j].getName(), User.class);
                            Method getMethod = pd.getReadMethod();//获得该属性的get方法
                            if(getMethod.invoke(user) != null){//执行get方法,获取所有对象中不为空的字段
                                //去重
                                hashSet.add(getMethod.getName().substring(3));
                            }
                        }
                    }
                    //设置表头顺序
                    List<String> arrList = new ArrayList<>();
                    int hashSetSice = hashSet.size();
                    for(int i=0 ; i<hashSetSice ; i++){
                        if(hashSet.contains("Id")){
                            arrList.add("Id");
                            hashSet.remove("Id");
                        }else if(hashSet.contains("Username")){
                            arrList.add("Username");
                            hashSet.remove("Username");
                        }else if(hashSet.contains("Sex")){
                            arrList.add("Sex");
                            hashSet.remove("Sex");
                        }else if(hashSet.contains("PassportIssueDate")){
                            arrList.add("PassportIssueDate");
                            hashSet.remove("PassportIssueDate");
                        }
                    }
                    head = arrList.toArray(new String[arrList.size()]);
                    headForBody = arrList.toArray(new String[arrList.size()]);
                    //表头多语言化
//                    transHeadInternational(head,lang);

                } catch (Exception e){
                    e.printStackTrace();
                }
            }

            //根据表头和list生成PDF
            generatePDF(head, headForBody, list, head.length);
        } catch (Exception e){
            e.printStackTrace();
        }


        return saveFilePathAndName;
    }

    /**
     * 为获取表头处理数据
     * @return
     */
    private User dealVoForHead(User user){
        //将不必要的字段置空,以免影响后面统计有值的字段数
        user.setPassword(null);

        //将为""的字段置空,当所有对象的某字段都为""或null时,该字段就不作为表头
        if(user.getId()==null || user.getId().equals("")){
            user.setId(null);
        }
        if(user.getSex()==null || user.getSex().equals("")){
            user.setSex(null);
        }
        if(user.getUsername()==null || user.getUsername().equals("")){
            user.setUsername(null);
        }
        if(user.getPassportIssueDate()==null || user.getPassportIssueDate().equals("")){
            user.setPassportIssueDate(null);
        }
        return user;
    }

    /**
     * 创建一个表格对象
     *
     * @param colNumber 表格的列数
     * @return 生成的表格对象
     */
    public com.lowagie.text.pdf.PdfPTable createTable(int colNumber) {
        com.lowagie.text.pdf.PdfPTable table = new com.lowagie.text.pdf.PdfPTable(colNumber);
        try {
            table.setTotalWidth(520);
            table.setLockedWidth(true);
            table.setHorizontalAlignment(Element.ALIGN_CENTER);
            table.getDefaultCell().setBorder(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return table;
    }
    /**
     * 为表格添加一个内容
     *
     * @param value     值
     * @param font      字体
     * @param align     对齐方式
     * @param colspan   占多少列
     * @param boderFlag 是否有有边框
     * @return 添加的文本框
     */
    public com.lowagie.text.pdf.PdfPCell createCell(String value, com.lowagie.text.Font font, int align, int colspan, boolean boderFlag) {
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setColspan(colspan);
        cell.setPhrase(new com.lowagie.text.Phrase(value, font));
        cell.setPadding(3.0f);
        if (!boderFlag) {
            cell.setBorder(0);
            cell.setPaddingTop(15.0f);
            cell.setPaddingBottom(8.0f);
        }
        return cell;
    }

    /**
     * 为表格添加一个内容
     *
     * @param value 值
     * @param font  字体
     * @param align 对齐方式
     * @return 添加的文本框
     */
    public com.lowagie.text.pdf.PdfPCell createCell(String value, com.lowagie.text.Font font, int align) {
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(align);
        cell.setPhrase(new com.lowagie.text.Phrase(value, font));
        return cell;
    }

    /**
     * 为表格添加一个内容
     *
     * @param value 值
     * @param font  字体
     * @return 添加的文本框
     */
    public com.lowagie.text.pdf.PdfPCell createCell(String value, com.lowagie.text.Font font) {
        com.lowagie.text.pdf.PdfPCell cell = new com.lowagie.text.pdf.PdfPCell();
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        cell.setPhrase(new com.lowagie.text.Phrase(value, font));
        return cell;
    }

    public <T> void generatePDF(String[] head, String[] headForBody, List<User> list, int colNum) {
        if(colNum == 0){
            colNum = 1;
        }
        // 创建一个表格
        com.lowagie.text.pdf.PdfPTable table = createTable(colNum);
        // 添加备注,靠左,不显示边框
        String addTitle=addTitle = "User Info:";
        table.addCell(createCell(addTitle, headfont, Element.ALIGN_LEFT, colNum, false));

        if (null != list && list.size() > 0) {
            Class classType = list.get(0).getClass();
            //设置表头
            for (int i = 0; i < colNum; i++) {
                table.addCell(createCell(head[i], keyfont, Element.ALIGN_CENTER));
            }
            //填充表格内容
            int size = list.size();
            for (int i = 0; i < size; i++) {
                User t = list.get(i);
                for (int j = 0; j < colNum; j++) {
                    //获得首字母
                    String firstLetter = headForBody[j].substring(0, 1).toUpperCase();

                    //获得get方法,getName,getAge等
                    String getMethodName = "get" + firstLetter + headForBody[j].substring(1);

                    Method method;
                    try {
                        //通过反射获得相应的get方法,用于获得相应的属性值
                        method = classType.getMethod(getMethodName, new Class[]{});
                        System.out.print(getMethodName + ":" + method.invoke(t, new Class[]{}) + ",");
                        //添加数据
                        table.addCell(createCell((method.invoke(t, new Class[]{})==null?"":method.invoke(t, new Class[]{})).toString(), textfont));
                    } catch (Exception e){
                        e.printStackTrace();
                    }
                }

                System.out.println("");
            }
        }

        try {
            //将表格添加到文档中
            document.add(table);
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        //关闭流
        document.close();
    }

效果如下:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值