zoukankan      html  css  js  c++  java
  • javaweb 报表生成(pdf excel)所需要用到的技术和思路

    pdf:

    目前开源、成熟、稳定的第三方包只有iText。而用iText生成PDF有三种方式:

    1. 调用iText API,用代码“写”出PDF,依赖包:com.itextpdf:itextpdf:5.5.11
    2. 结合XmlWorker,从HTML模板生成PDF,依赖包:com.itextpdf.tool:xmlworker:5.5.11
    3. 结合Flying Saucer,从HTML模板生成PDF,依赖包:org.xhtmlrenderer:flying-saucer-pdf-itext5:9.1.6

    这一段是复制别人的,我使用的是第二种方法,直接html转pdf,这种方式只要用对了就特别方便,如果用代码写出pdf,那得上千行java代码了,非常麻烦

    开始配置:

    网上查找了很久,发现下面这个链接帮我避免了很多坑,这些依赖组合好就能正常使用了

    http://www.zhimengzhe.com/HTMLjiaocheng/259505.html

    所需依赖:

    注意:一定要按此版本号引入,不然会出现很多错误,包括“中文乱码、中文不输出或直接报错”等异常!

            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itextpdf</artifactId>
                <version>5.4.3</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf</groupId>
                <artifactId>itext-asian</artifactId>
                <version>5.2.0</version>
            </dependency>
            <dependency>
                <groupId>com.itextpdf.tool</groupId>
                <artifactId>xmlworker</artifactId>
                <version>5.4.1</version>
            </dependency>
            <dependency>
                <groupId>org.jsoup</groupId>
                <artifactId>jsoup</artifactId>
                <version>1.10.1</version>
            </dependency>

    依赖好了之后,又搜了很久,找到了支持中文的解决方案:

    最简单 iText 的 PDF 生成方案(含中文解决方案)HTML 转为 PDF  (下面的这个方法的总结参考自此链接)

    要点:

    所有的单标签必须闭合(所有单标签必须全部闭合,否则只要有一个没闭合,都会报错 RuntimeWorkerException,

    例如: com.itextpdf.tool.xml.exceptions.RuntimeWorkerException: Invalid nested tag head found, expected closing tag meta.  注:这里的报错不会给出源文件中出错位置的行数,但是它会给出报错的标签,这里给出的是meta没有正确被关闭,事实上,这里给出的报错已经很详细了,在head里找到了无效嵌套,预期的结束了meta标签,也就是说meta没闭合,如果是成对标签少了闭合标签也会抛出异常,或者单标签未闭合,也会抛出异常,所以其实还是比较好找的,但是写的时候一开始就得注意好标签的闭合问题

    另一个要点:如果在文本或者非标签的地方使用了 < > 这样的特殊字符,必须写成实体字符,否则程序在转pdf的时候会当成正常标签处理,导致异常关闭标签,就报错了

    ,成对标签正常写即可,支持一些基本的html、css,不支持外部link script,不支持js,body以外必须全部按照下面的格式来写,body以内的,注意每个span都必须配上字体的样式,否则不能显示pdf中文文本

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    </head>
    <body screen_capture_injected="true" ryt11773="1">
        <p>
            <span style="font-size:12.0pt; font-family:MS Mincho">長空</span> <span
                style="font-size:12.0pt; font-family:Times New Roman,serif">(Broken
                Sword),</span> <span style="font-size:12.0pt; font-family:MS Mincho">秦王殘劍</span>
            <span style="font-size:12.0pt; font-family:Times New Roman,serif">(Flying
                Snow),</span> <span style="font-size:12.0pt; font-family:MS Mincho">飛雪</span>
            <span style="font-size:12.0pt; font-family:Times New Roman,serif">(Moon),
            </span> <span style="font-size:12.0pt; font-family:MS Mincho">如月</span> <span
                style="font-size:12.0pt; font-family:Times New Roman,serif">(the
                King), and</span> <span style="font-size:12.0pt; font-family:MS Mincho">秦王</span>
            <span style="font-size:12.0pt; font-family:Times New Roman,serif">(Sky).</span>
        </p>
    </body>
    </html>

    再使用java转换代码进行转换即可:

    package com.zhouqian.itext;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.nio.charset.Charset;
    
    import com.itextpdf.text.Document;
    import com.itextpdf.text.DocumentException;
    import com.itextpdf.text.pdf.PdfWriter;
    import com.itextpdf.tool.xml.XMLWorkerHelper;
     
     
    public class D07_ParseHtmlAsian {
     
        
        
        public static final String HTML = "E:/Dropbox/document/java/designPattern/data/hero.html";
        public static final String DEST = "E:/Dropbox/document/java/designPattern/data/hero.pdf";
     
        /**
         * Creates a PDF with the words "Hello World"
         * @param file
         * @throws IOException
         * @throws DocumentException
         */
        public void createPdf(String file) throws IOException, DocumentException {
            // step 1
            Document document = new Document();
            // step 2
            PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
            // step 3
            document.open();
            // step 4
            XMLWorkerHelper.getInstance().parseXHtml(writer, document,
                    new FileInputStream(HTML), Charset.forName("UTF-8"));
            // step 5
            document.close();
        }
     
        /**
         * Main method
         */
        public static void main(String[] args) throws IOException, DocumentException {
            File file = new File(DEST);
            file.getParentFile().mkdirs();
            new D07_ParseHtmlAsian().createPdf(DEST);
        }
    }

    在指定路径下就可以得到 PDF 结果:

     我测试之后发现能够正常使用,nice

    PDF中放入统计图:

    需要用到 jfreechart 来生成图,然后再把图片引入html,再转pdf

    https://www.yiibai.com/jfreechart

    发现这个易百教程上面的java教程很全面,基本上涵盖了java的各类技术和组件,都是一些生产上使用广泛的组件技术,可以用来实现各种需求

    Excel:

    excel的话,使用poi+模板的方式就可以了

    报表生成思路:

    pdf:先写一个基本的符合pdf生成标准(要点:所有的单标签必须闭合,成对标签正常些即可,支持一些基本的html、css,不支持外部link script,不支持js,body以外必须全部按照下面的格式来写,body以内的,注意每个span都必须配上字体的样式,否则不能显示pdf中文文本)的html,然后用jsp的方式在特定位置填充数据,想要生成pdf的时候,让程序自己去访问刚才的jsp页面(直接让程序访问localhost的页面位置进行下载即可,使用http/https通道访问),访问得到的就是已经填充好数据的html了,然后下载,文件名生成时规定成.html格式的,然后再用上面的html转pdf即可得到pdf了。

    (待续)

     

  • 相关阅读:
    由于版本依赖造成的YUM段错误
    CodeDom系列事件(event)定义和反射调用
    CodeSmith模板引擎系列二文件目录树
    F#初试打印目录文件树
    在IIS上SSL的部署和启动SSL安全
    CodeDom系列二程序基本结构符号三角形问题
    CodeDom系列目录
    CodeDom系列四Code生成
    CodeDom六实体类生成示例
    CodeDom系列五动态编译
  • 原文地址:https://www.cnblogs.com/kinome/p/9667988.html
Copyright © 2011-2022 走看看