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

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

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

  请尊重作者劳动成果,转载请标明原文链接:


前提准备:

 

  1. 项目中至少需要引入的jar包,注意版本:

    a) core-renderer.jar

    b) freemarker-2.3.16.jar

    c) iText-2.0.8.jar

    d) iTextAsian.jar

上代码:

注释: 此类为自定义的Tag类的基类,在action中怎么放的数据,在ftl中就怎么取数据,简洁明了。

 1. 自定义Tag类的基类

复制代码
/**
 * 通用的生成pdf预览和生成打印的html文件
 * 
 * @author xg君
 * 
 */
public abstract class PDFTag extends BodyTagSupport {

    private static final long serialVersionUID = 1L;

    // 标签属性变量
    private String json = "";
    private String tempDir = "";
    // 非标签属性变量
    private Map<String, Object> rootMap = new HashMap<String, Object>();
    private String templateStr = null;
    private String freemarkereConfigurationBeanName = null;
    private String fileName = null;
    private String basePath = null;
    private String fileEncoding = "utf-8";

    @Override
    public int doStartTag() throws JspException {
        setConfigParams();
        WebApplicationContext application = WebApplicationContextUtils.getWebApplicationContext(pageContext
                .getServletContext());
        doServiceStart();
        String ctx = (String) pageContext.getAttribute("ctx");
        rootMap.put("ctx", ctx);
        Map<String, Object> map = parseJSON2Map(json);
        rootMap.putAll(map);
        if (freemarkereConfigurationBeanName == null) {
            try {
                throw new CstuException("FreemarkereConfigurationBeanName不能为空!");
            } catch (CstuException e) {
                e.printStackTrace();
            }
        }
        Configuration cptFreemarkereConfiguration = (Configuration) application
                .getBean(freemarkereConfigurationBeanName);
        try {
            if (templateStr == null) {
                throw new CstuException("模板文件不能为空!");
            }
            Template template = cptFreemarkereConfiguration.getTemplate(templateStr);
            if (basePath == null) {
                throw new CstuException("文件的基本路径(父路径)不能为空!");
            }
            File htmlPath = new File(tempDir + File.separator + basePath);
            if (!htmlPath.exists()) {
                htmlPath.mkdirs();
            }
            if (fileName == null) {
                throw new CstuException("生成的html文件名不能为空!");
            }
            File htmlFile = new File(htmlPath, File.separator + fileName);
            if (!htmlFile.exists()) {
                htmlFile.createNewFile();
            }
            BufferedWriter out = new BufferedWriter(
                    new OutputStreamWriter(new FileOutputStream(htmlFile), fileEncoding));
            template.process(rootMap, out);
            out.flush();
            doServiceDoing();
            // 显示在页面
            template.process(rootMap, pageContext.getResponse().getWriter());
        } catch (Exception e) {
            e.printStackTrace();
        }

        doServiceEnd();
        return SKIP_BODY;
    }

    /**
     * 配置基础参数,如
     */
    public abstract void setConfigParams();

    /**
     * 业务处理方法-开始 填充数据
     * 
     * @return
     */
    public abstract void doServiceStart();

    /**
     * 业务处理方法-执行中 备用,可空实现,若rootMap中存在双份数据则可在此处填充判断条件
     * 
     * @return
     */
    public abstract void doServiceDoing();

    /**
     * 业务处理方法-结束 清空rootMap并调用垃圾回收,也可空实现
     * 
     * @return
     */
    public abstract void doServiceEnd();

    /**
     * 将元素放入rootMap中
     */
    public void putKV(String key, Object value) {
        rootMap.put(key, value);
    }

    /**
     * 将map放入rootMap中
     * 
     * @param m
     */
    public void putMap(Map m) {
        rootMap.putAll(m);
    }

    public void clear() {
        rootMap.clear();
        rootMap = null;
    }

    /**
     * 移除元素
     * 
     * @param key
     * @return
     */
    public Object remove(String key) {
        return rootMap.remove(key);
    }

    public static Map<String, Object> parseJSON2Map(String jsonStr) {
        Map<String, Object> map = new HashMap<String, Object>();
        JSONObject json = JSONObject.fromObject(jsonStr);
        for (Object k : json.keySet()) {
            Object v = json.get(k);
            if (v instanceof JSONArray) {
                List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
                Iterator<JSONObject> it = ((JSONArray) v).iterator();
                while (it.hasNext()) {
                    JSONObject json2 = it.next();
                    list.add(parseJSON2Map(json2.toString()));
                }
                map.put(k.toString(), list);
            } else {
                map.put(k.toString(), v);
            }
        }
        return map;
    }

    public String getJson() {
        return json;
    }

    public void setJson(String json) {
        this.json = json;
    }

    public String getTempDir() {
        return tempDir;
    }

    public void setTempDir(String tempDir) {
        this.tempDir = tempDir;
    }

    public String getTemplateStr() {
        return templateStr;
    }

    public void setTemplateStr(String templateStr) {
        this.templateStr = templateStr;
    }

    public String getFreemarkereConfigurationBeanName() {
        return freemarkereConfigurationBeanName;
    }

    public void setFreemarkereConfigurationBeanName(String freemarkereConfigurationBeanName) {
        this.freemarkereConfigurationBeanName = freemarkereConfigurationBeanName;
    }

    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }

    public String getBasePath() {
        return basePath;
    }

    public void setBasePath(String basePath) {
        this.basePath = basePath;
    }

    public String getFileEncoding() {
        return fileEncoding;
    }

    public void setFileEncoding(String fileEncoding) {
        this.fileEncoding = fileEncoding;
    }

}
复制代码

 

注释: setConfigParams方法是用于调用接口定义的配置参数的方法,如:templateStr,basePath等,doServiceStart,doServiceDoing和doServiceEnd等方法用于处理业务逻辑,比如我的需求是做出合同在一个页面显示,要分页,要加水印,但生成的pdf样式与预览的是不同的,所以我加了一个doServiceDoing中给rootMap添加判断条件,这样就能一个flt文件作出两种效果(预览和打印),当然如果预览和打印要一样的效果,doServiceDoing方法可以空实现。这四个方法总结一下就是:

1. setConfigParams : 配置参数

2. doServiceStart : 填充数据/条件

3. doServiceDoing : 填充数据/条件,到这里是个分界线,此方法之前,rootMap数据先进入html再进入浏览器(预览),此方法之后,rootMap数据会再次进入html文件,结束,所以此处可写判断

4. doServiceEnd : 可有可无,我还是写上了,万一哪天的数据集太大,此处便可以在数据填充完后,清理掉,节省内存空间

 

2. PDFTag的子类

复制代码
/**
 * 用户自定义PDFTag类
 * 
 * @author xg君
 * 
 */
public class ViewPDFTag extends PDFTag {
    private static final long serialVersionUID = 4528567203497016087L;

    private String prjNature = "";
    private String bookName = "";
    private String prjCode = "";

    /**
     * 用户自定义的配置参数
     */
    public PDFConfigurationInterface pDFConfigurationInterface = new PDFConfigurationInterface() {

        @Override
        public void configTemplateStr() {
            // 横,纵向
            if (prjNature.equalsIgnoreCase("2") || prjNature.equalsIgnoreCase("1")) {
                setTemplateStr("wj-project-print.ftl");
            }
        }

        @Override
        public void configFreemarkereConfigurationBeanName() {
            setFreemarkereConfigurationBeanName("cptFreemarkereConfiguration");
        }

        @Override
        public void configFileName() {
            // 填入html文件
            setFileName(prjCode + ".html");
        }

        @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


签名:雪糕君

  

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
PDFJava是一款用于处理PDF文档的Java库,可以实现PDF文档的生成、编辑和预览等功能。以下是PDFJava代码下载预览和签章操作示例: 1. 下载PDFJava代码PDFJava官网(https://pdfjava.org/)下载PDFJava的最新版本,解压后得到PDFJava的jar包和相关的文档。 2. 预览PDF文档 使用PDFJava可以实现PDF文档的预览功能,示例代码如下: ```java import org.pdfjava.core.PDFDocument; import org.pdfjava.viewer.PDFViewer; public class PDFPreviewer { public static void main(String[] args) throws Exception { PDFDocument document = new PDFDocument("example.pdf"); PDFViewer viewer = new PDFViewer(document); viewer.preview(); } } ``` 上述代码会打开名为example.pdfPDF文档并进行预览。 3. 对PDF文档进行签章 PDFJava还可以实现对PDF文档的签章操作,示例代码如下: ```java import java.awt.Color; import java.awt.Image; import java.io.File; import java.io.FileInputStream; import java.security.KeyStore; import java.security.PrivateKey; import java.security.cert.Certificate; import org.pdfjava.core.PDFDocument; import org.pdfjava.sign.SignatureAppearance; import org.pdfjava.sign.SignatureOptions; import org.pdfjava.sign.Signer; public class PDFSigner { public static void main(String[] args) throws Exception { PDFDocument document = new PDFDocument("example.pdf"); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(new FileInputStream("example.pfx"), "password".toCharArray()); String alias = (String) ks.aliases().nextElement(); PrivateKey key = (PrivateKey) ks.getKey(alias, "password".toCharArray()); Certificate[] chain = ks.getCertificateChain(alias); Image image = ImageIO.read(new File("signature.png")); SignatureAppearance appearance = new SignatureAppearance(); appearance.setSignerName("John Doe"); appearance.setLocation("New York"); appearance.setReason("Testing"); appearance.setImage(image); appearance.setImagePosition(200, 200); appearance.setSignatureColor(Color.BLACK); SignatureOptions options = new SignatureOptions(); options.setPage(1); options.setAppearance(appearance); Signer signer = new Signer(document, key, chain); signer.sign(options); document.save("example-signed.pdf"); } } ``` 上述代码会对名为example.pdfPDF文档进行签章操作,并保存为example-signed.pdf。在签章操作中,需要提供证书和私钥等信息,并设置签章的位置、颜色和图片等属性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值