velocity+itext渲染把HTML转化成PDF

pom:

		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>itextpdf</artifactId>
			<version>5.5.11</version>
		</dependency>
		<dependency>
			<groupId>com.itextpdf.tool</groupId>
			<artifactId>xmlworker</artifactId>
			<version>5.5.6</version>
		</dependency>
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>itext-asian</artifactId>
			<version>5.2.0</version>
		</dependency>

页面层面: hello.vm

<html>
<style>
    *{font-family: SimSun;}
</style>
<style type="text/css" media=print>
    .noprint{display:none; }
</style>
<body>
<div class="noprint">
    akshdkfhaksdhf
</div>
<h1>${city}</h1>
</body>
</html>

测试进入页面:

    @RequestMapping("testView")
    public ModelAndView testView(ModelMap modelMap){
        modelMap.put("city", "上海市");
        return new ModelAndView("resources/hello.vm", modelMap);
    }

下载PDF接口:

    @RequestMapping("testDowenload")
    public void testDowenload(HttpServletResponse response){
        try {
            response.setCharacterEncoding("utf-8");
            response.setContentType("multipart/form-data");
            // 定义PDF文件名
            response.setHeader("Content-Disposition", "attachment;fileName=" + UUID.randomUUID().toString() + ".pdf");

            //获取对应网页页面的模板
            VelocityEngine velocityEngine = new VelocityEngine();
            velocityEngine.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
            velocityEngine.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
            velocityEngine.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
            velocityEngine.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
            velocityEngine.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
            velocityEngine.init();    // 初始化VelocityEngine 
            Template t = velocityEngine.getTemplate("resources/hello.vm");
            //取得velocity的上下文context,往vm中写入信息
            VelocityContext context = new VelocityContext();
            // 注意:自定义了velocity工具类 应在context加上
            // context.put("velocityTool", new VelocityTool())
            context.put("city", "上海");
            // 写入流
            StringWriter writer = new StringWriter();
            //把数据填入上下文
            t.merge(context, writer);

            File targetFile = new File(UUID.randomUUID().toString() + ".pdf");

            // writer得到页面代码,创建字节数组输入流
            ByteArrayInputStream htmlInputStream = new ByteArrayInputStream(writer.toString().getBytes());
            
            // 得到Document,OutputStream,PdfWriter 对象,为生成PDF接口(parseXHtml)做准备
            Document document = new Document(PageSize.A4);
            OutputStream os = new FileOutputStream(targetFile);
            PdfWriter pdfWriter = PdfWriter.getInstance(document, os);
            document.open();

            final List<Element> pdfeleList = new ArrayList<Element>();
            ElementHandler elemH = new ElementHandler() {
                public void add(final Writable w) {
                    if (w instanceof WritableElement) {
                        pdfeleList.addAll(((WritableElement) w).elements());
                    }

                }
            };

            XMLWorkerHelper.getInstance().parseXHtml(elemH, new InputStreamReader(htmlInputStream));

            for (Element ele : pdfeleList) {
                if (ele instanceof LineSeparator
                        || ele instanceof WritableDirectElement) {
                    continue;
                }
                // 跨页问题
                if(ele instanceof PdfDiv){
                    ArrayList<Element> list =  ((PdfDiv) ele).getContent();
                    for (Element element : list) {
                        if(element instanceof PdfPTable){
                            ((PdfPTable) element).setSplitLate(true);
                            ((PdfPTable) element).setKeepTogether(true);
                            ((PdfPTable) element).setSplitRows(true);
                            ArrayList<PdfPRow> rows = ((PdfPTable) element).getRows();
                            for (int i = 0 ;i<rows.size();i++){
                                if(rows.get(i).hasRowspan()){
                                    PdfPCell[] cells = rows.get(i).getCells();
                                    for (PdfPCell cell : cells) {
                                        if(cell != null && cell.getRowspan()>1){
                                            ((PdfPTable) element).keepRowsTogether(i,i+cell.getRowspan());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                document.add(ele);
            }


            document.close();
            os.flush();
            os.close();
            htmlInputStream.close();

        // 获取PDF页数
        FileInputStream fileInputStream = new FileInputStream(targetFile);
        PdfReader inputPDF = new PdfReader(fileInputStream);
        Integer totalPages = inputPDF.getNumberOfPages();

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值