java原装代码完成pdf在线预览和pdf打印及下载

2/10/2017来源:ASP.NET技巧人气:1081

这是我在工作中,遇到这样需求,完成需求后,总结的成果,就当做是工作笔记,以免日后忘记,当然,能帮助到别人是最好的啦!下面进入正题:

  若有不正之处请多多谅解,并欢迎批评指正。

  请尊重作者劳动成果,"); } @Override public void configFileEncoding() { // 默认utf-8 } @Override public void configBasePath() { setBasePath("html_pdf"); } }; @Override public void doServiceStart() { putKV("PRjNature", prjNature); putKV("bookName", bookName); putKV("flag", "0"); } @Override public void doServiceDoing() { putKV("flag", "1"); } @Override public void doServiceEnd() { clear(); System.gc(); } public String getPrjNature() { return prjNature; } public void setPrjNature(String prjNature) { this.prjNature = prjNature; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getPrjCode() { return prjCode; } public void setPrjCode(String prjCode) { this.prjCode = prjCode; } @Override public void setConfigParams() { pDFConfigurationInterface.configTemplateStr(); pDFConfigurationInterface.configFreemarkereConfigurationBeanName(); pDFConfigurationInterface.configFileName(); pDFConfigurationInterface.configBasePath(); pDFConfigurationInterface.configFileEncoding(); } } 复制代码

注释: PDFConfigurationInterface 是自定义的标签参数配置接口,子类必须定义一个该接口的实现类的成员变量或定义一个成员变量内部类,并在setConfigParams方法中调用使其生效。

子类的成员变量接收在tld文件中配置的属性。

3. 自定义的标签参数配置接口

复制代码
/**
 * PdfTag类的配置
 * 
 * @author xg君
 * 
 */
public interface PDFConfigurationInterface {

    /**
     * 设置模板名称
     */
    void configTemplateStr();

    /**
     * 设置配置的FreemarkereConfigurationBean的名称
     */
    void configFreemarkereConfigurationBeanName();

    /**
     * 设置生成的html文件名称
     */
    void configFileName();

    /**
     * 设置生成的html文件的基本路径(父目录)
     */
    void configBasePath();

    /**
     * 设置文件编码,默认utf-8
     */
    void configFileEncoding();
}
复制代码

 

4. 自定义异常类

复制代码
/**
 * 自定义异常类
 * 
 * @author Administrator
 * 
 */
public class CstuException extends Exception {

    private static final long serialVersionUID = 4266461814747405870L;

    public CstuException(String msg) {
        super(msg);
    }
}
复制代码

 

5. tld文件配置

复制代码
<tag>
        <name>print</name>
        <tagclass>com.iris.taglib.web.PreviewPDFTag</tagclass>
        <bodycontent>jsp</bodycontent>
        <attribute>
            <name>json</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>prjNature</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>bookName</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>tempDir</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
        <attribute>
            <name>prjCode</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>
复制代码

6. action

复制代码
/**
 * 处理PDF导出
 * 
 */
@Namespace("/export")
@Results({ @Result(name = "Exceltemplate", location = "/WEB-INF/content/pdf/export-pdf.jsp"),
        @Result(name = "exprotPdf2", location = "/WEB-INF/content/project/project/export/export-pdf2.jsp") })
public class ExportPdfAction extends ActionSupport {

    private static final long serialVersionUID = -5454188364706173477L;

    @Value("${tempDir}")
    private String tempDir;

    @Value("${pdfFont}")
    private String pdfFont;

    @Value("${staticResRootDir}")
    private String staticResRootDir;

    @Value("${staticResRootDir2}")
    private String staticResRootDir2;

    @Value("${WaterMarkImgDir}")
    private String waterMarkImgDir;

    @Autowired
    private ProjectService projectService;

    @Autowired
    private PersonService personService;

    @Autowired
    private ConstDictionaryService constDictionaryService;

    @Autowired
    private FdPlanDetailService fdPlanDetailService;

    @Autowired
    private ServiceFactory serviceFactory;

    @Action("exprotPdf2")
    public String exprotPdf2() {
        String prjCode = Struts2Utils.getParameter("prjCode");
        prjCode = Struts2Utils.decodeDesString(prjCode);
        Project project = projectService.getProjectById(Long.parseLong(prjCode));
        Map<String, String> baseInfo = new HashMap<String, String>();

        baseInfo.put("tempDir", tempDir);

        // 项目编号
        baseInfo.put("prjCode", prjCode);

        // 项目类型
        String prjNature = project.getPrjNature();
        baseInfo.put("prjNature", prjNature);

        // 水印名称格式:watermark+"-"+prjNature
        baseInfo.put("waterMarkImg", waterMarkImgDir + File.separator + "watermark-" + prjNature + ".png");

        // 负责人
        Person person = personService.getPerson(project.getPsnCode());
        String zhName = person.getZhName();
        baseInfo.put("zhName", addStr(9, "<br/>", zhName));

        // 项目编号
        String prjNo = project.getPrjNo();
        baseInfo.put("prjNo", prjNo);

        // 项目来源
        ConstDictionary cd = constDictionaryService.findCdByCategoryCode("project_from", project.getGrantNo());
        String project_from = cd.getzh_cn_caption();
        baseInfo.put("project_from", addStr(9, "<br/>", project_from));

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        // 起止年限
        String startDate = sdf.format(project.getStartDate());
        String endDate = sdf.format(project.getEndDate());
        String startEndDate = startDate + "~" + endDate;
        baseInfo.put("startEndDate", startEndDate);

        // 项目类别--资助类别
        String grantName = project.getGrantName();
        baseInfo.put("grantName", addStr(9, "<br/>", grantName));

        // 合同金额
        String totalAmt = project.getTotalAmt().toString();

        BigDecimal totalAmt_ = checkNumber(totalAmt);
        baseInfo.put("totalAmt", totalAmt_.toString());

        // 项目名称
        String zhTitle = project.getZhTitle();
        baseInfo.put("zhTitle", addStr(38, "<br/>", zhTitle));

        List<Map<String, String>> ps = null;
        try {
            ps = getMembers(project.getPrjxml());
        } catch (Exception e) {
            e.printStackTrace();
        }

        String bookName = "";
        // 判断项目类型
        Map<String, Object> itemMap = new HashMap<String, Object>();
        if (prjNature.equalsIgnoreCase("1")) {
            bookName = "第一份合同";
            // 获取fdPlanDetail
            List<Map<String, Object>> list = fdPlanDetailService.getFdPlanDetailsByPrjCode(Long.parseLong(prjCode));

            // test
            /*
             * Map<String, Object> test = new HashMap<String, Object>(); test.put("itemValue", "6");
             * test.put("itemName", "差旅费"); test.put("remark", "xxxxx"); list.add(test);
             */

            for (Map<String, Object> m : list) {
                String key = (String) m.get("ITEMNAME");
                BigDecimal itemValue = (BigDecimal) m.get("ITEMVALUE");
                BigDecimal proportion = new BigDecimal(0.00);
                if (itemValue != null && totalAmt_.compareTo(new BigDecimal("0.00")) != 0) {
                    proportion = itemValue.divide(totalAmt_, 6, BigDecimal.ROUND_HALF_EVEN);
                }
                if (itemValue == null) {
                    itemValue = new BigDecimal("0.00");
                }
                proportion = checkNumber(proportion.toString());

                Map<String, Object> data = new HashMap<String, Object>();
                // 添加比例
                data.put("proportion", proportion.toString());
                // 检测金额规范
                BigDecimal amt = checkNumber(itemValue.toString());
                data.put("itemValue", amt.toString());
                // remark
                String remark = (String) m.get("REAMRK");
                data.put("remark", remark == null ? "" : remark);

                itemMap.put(key, data);
            }
        } else if (prjNature.equalsIgnoreCase("2")) {
            bookName = "第二份合同";
        }

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("baseInfo", baseInfo);
        map.put("projectMember", ps);
        map.put("itemMap", itemMap);
        map.put("psCount", ps.size());
        map.put("psSum", 25 - ps.size());

        String json = JSONObject.fromObject(map).toString();
        Struts2Utils.getRequest().setAttribute("jsonData", json);
        Struts2Utils.getRequest().setAttribute("prjNature", prjNature);
        Struts2Utils.getRequest().setAttribute("bookName", bookName);
        Struts2Utils.getRequest().setAttribute("tempDir", tempDir);
        Struts2Utils.getRequest().setAttribute("prjCode", prjCode);
        return "exprotPdf2";
    }

    public List<Map<String, String>> getMembers(String xmlData) throws Exception {
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        Document doc = DocumentHelper.parseText(xmlData);
        Node ps = doc.selectSingleNode("/data/project/persons");
        List<Node> psList = ps.selectNodes("person");
        String totalAmt = doc.selectSingleNode("/data/project/basic_info/total_amt").getText();
        for (Node person : psList) {
            Map<String, String> map = new HashMap<String, String>();
            Node fund_proportion = person.selectSingleNode("fund_proportion");
            String fund_proportion_text = "";
            if (fund_proportion == null) {
                map.put("proportion", "0.00");
                map.put("fpAmt", "0.00");
            } else {
                fund_proportion_text = fund_proportion.getText();
                BigDecimal fp = new BigDecimal(fund_proportion_text);
                fp = fp.multiply(new BigDecimal("0.01"));
                fp = checkNumber(fp.toString());
                map.put("proportion", fp.toString());
                BigDecimal fdAmt_ = fp.multiply(new BigDecimal(totalAmt));
                fdAmt_ = checkNumber(fdAmt_.toString());
                map.put("fpAmt", fdAmt_.toString());
            }

            Node psn_name = person.selectSingleNode("psn_name");
            String psn_name_text = psn_name.getText();
            map.put("zhName_p", addStr(9, "<br/>", psn_name_text));

            Node psn_work = person.selectSingleNode("psn_work");
            String psn_work_text = "";
            if (psn_work != null) {
                psn_work_text = psn_work.getText();
            }
            map.put("work", addStr(9, "<br/>", psn_work_text));

            Node dept_code_name = person.selectSingleNode("dept_code_name");
            String dept_code_name_text = "";
            if (dept_code_name != null) {
                dept_code_name_text = dept_code_name.getText();
            }
            map.put("deptName", addStr(9, "<br/>", dept_code_name_text));

            Node psn_type_name = person.selectSingleNode("psn_type_name");
            String psn_type_name_text = "";
            if (psn_type_name != null) {
                psn_type_name_text = psn_type_name.getText();
            }
            map.put("psnTypeName", psn_type_name_text);

            list.add(map);
        }
        return list;
    }

    /**
     * 为字符串添加指定字符
     * 
     * @param num
     * @param splitStr
     * @param str
     * @return
     */

    public String addStr(int num, String splitStr, String str) {
        StringBuffer sb = new StringBuffer();
        String temp = str;
        int len = str.length();
        while (len > 0) {
            if (len < num) {
                num = len;
            }
            sb.append(temp.substring(0, num)).append(splitStr);
            temp = temp.substring(num);
            len = temp.length();
        }
        return sb.toString();
    }


    /**
     * 两个数字/英文
     * 
     * @param str
     * @param num
     * @return 最终索引
     */
    public static int getEndIndex(String str, double num) {
        int idx = 0;
        int count = 0;
        double val = 0.00;
        // 判断是否是英文/数字
        for (int i = 0; i < str.length(); i++) {
            if ((str.charAt(i) >= 'A' && str.charAt(i) <= 'Z') || (str.charAt(i) >= 'a' && str.charAt(i) <= 'z')
                    || Character.isDigit(str.charAt(i))) {
                val += 0.50;
            } else {
                val += 1.00;
            }
            count = i + 1;
            if (val >= num) {
                idx = i;
                break;
            }
        }
        if (idx == 0) {
            idx = count;
        }
        return idx;
    }

    /**
     * 下载pdf文件
     * 
     * @return
     */
    @Action("downLoad")
    public String downLoad() {
        String prjCode = Struts2Utils.getParameter("prjCode");
        String basePath = "html_pdf";
        Project project = projectService.getProjectById(Long.parseLong(prjCode));
        String zhTitle = project.getZhTitle();
        FileOutputStream fos = null;
        // html
        File htmlFile = new File(tempDir + File.separator + basePath + File.separator + prjCode + ".html");
        String pdfPath = tempDir + File.separator + basePath + File.separator + zhTitle + ".pdf";
        try {
            fos = new FileOutputStream(pdfPath);

            String url = htmlFile.toURI().toURL().toString();
            ITextRenderer renderer = new ITextRenderer();
            renderer.setDocument(url);
            ITextFontResolver fontResolver = renderer.getFontResolver();
            fontResolver.addFont(pdfFont + File.separator + "SimSun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            renderer.layout();
            renderer.createPDF(fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // 添加水印
        String wartermark = "";
        if (project.getPrjNature().equalsIgnoreCase("1")) {
            // 横向
            wartermark = "CTGU横向科研项目立项通知书";
        } else if (project.getPrjNature().equalsIgnoreCase("2")) {
            // 纵向
            wartermark = "CTGU纵向科研项目立项通知书";
        }
        String wm_pdf = tempDir + File.separator + "wm_" + project.getZhTitle() + ".pdf";
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(wm_pdf));
            waterMark(bos, pdfPath, wartermark, staticResRootDir2 + File.separator + waterMarkImgDir + File.separator
                    + "watermark-" + project.getPrjNature() + ".png");
        } catch (Exception e2) {
            e2.printStackTrace();
        }
        // 拿到pdf
        File pdfFile = new File(wm_pdf);
        BufferedOutputStream out = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(pdfFile);
            HttpServletResponse response = Struts2Utils.getResponse();
            response.reset();
            String fileName = zhTitle + ".pdf";
            String fileName2 = URLEncoder.encode(fileName, "UTF-8");
            String agent = Struts2Utils.getRequest().getHeader("USER-AGENT");

            // IE
            if (null != agent && -1 != agent.indexOf("MSIE")) {
                fileName2 = new String(fileName.getBytes("GBK"), "ISO8859-1");
            } else if (null != agent && -1 != agent.indexOf("Mozilla")) {
                fileName2 = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            }
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName2 + "\"");
            response.setContentType(FileContentTypes.getContentType(zhTitle + ".pdf"));
            out = new BufferedOutputStream(response.getOutputStream());
            byte[] buffer = new byte[16 * 1024];
            int len = 0;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        // 清理残留文件
        // if (htmlFile.exists()) {
        // htmlFile.delete();
        // }
        File temp_file = new File(pdfPath);
        if (temp_file.exists()) {
            temp_file.delete();
        }
        if (pdfFile.exists()) {
            pdfFile.delete();
        }
        return null;
    }
  
  

    public BigDecimal checkNumber(String number) {
        // 初始化为6位小数
        DecimalFormat df = new DecimalFormat("0.000000");
        String num = df.format(Double.parseDouble(number));
        BigDecimal bd = new BigDecimal(num);
        String val = bd.toString();
        val = val.replaceAll("^(0+)", "");
        val = val.replaceAll("(0+)$", "");
        int idx = val.indexOf(".");
        int len = val.substring(idx + 1).length();
        if (len < 2) {
            if (len == 0 && idx == 0) {
                bd = new BigDecimal("0.00");
            } else {
                bd = new BigDecimal(val).setScale(2);
            }
        } else {
            bd = new BigDecimal(val).setScale(len);
        }
        return bd;
    }

    private String replaceStr(String str, String reVal) {
        Pattern pattern = Pattern.compile("^" + reVal + "+|" + reVal + "+$");
        Matcher matcher = pattern.matcher(str);
        return matcher.replaceAll("");
    }

    /**
     * 添加水印
     */
    private void waterMark(BufferedOutputStream bos, String input, String waterMarkName, String imagePath) {
        try {
            PdfReader reader = new PdfReader(input);
            PdfStamper stamper = new PdfStamper(reader, bos);
            int total = reader.getNumberOfPages() + 1;
            PdfContentByte content;
            BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);

            PdfGState gs = new PdfGState();
            for (int i = 1; i < total; i++) {
                content = stamper.getOverContent(i);// 在内容上方加水印
                content.setGState(gs);
                content.beginText();

                Image image = Image.getInstance(imagePath);
                image.setAbsolutePosition(-30, 200);
                image.scalePercent(80);
                content.addImage(image);

                content.endText();
            }
            stamper.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
复制代码

7. ftl文件(模板文件)

复制代码
<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml">  
  <head>  
    <title>打印预览</title>
     <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
......
</head>
<body>
</body>
</html>
  
复制代码

预览效果:

 

打印效果:

 

  过几天周末,我会上传一个独立的demo到github上,大家有问题可以来问我哦~。

       我的另一篇文章地址:http://www.cnblogs.com/king-xg/p/6369291.html

签名:雪糕君