• 一次java导出pdf的经历


    近期由于工作需要,需要将html代码导入到pdf中,经过了几种pdf的方案对比后发现IText是最简单和便捷的一种方式,于是乎采用了Itext。

    PDF生成

    第一步:导入Maven依赖

    <!--pdf生成工具类-->
          <dependency>
              <groupId>com.itextpdf</groupId>
              <artifactId>itextpdf</artifactId>
              <version>5.4.2</version>
          </dependency>
          <dependency>
              <groupId>com.itextpdf.tool</groupId>
              <artifactId>xmlworker</artifactId>
              <version>5.4.1</version>
          </dependency>
          <dependency>
              <groupId>com.itextpdf</groupId>
              <artifactId>itext-asian</artifactId>
              <version>5.2.0</version>
          </dependency>
          <dependency>
              <groupId>org.xhtmlrenderer</groupId>
              <artifactId>flying-saucer-pdf</artifactId>
              <version>9.0.3</version>
          </dependency>

    第二步:直接上代码

    public static void main(String[] args) throws IOException
        {
            String html = PDFKit.readFileByUrl("http://127.0.0.1/export/1/1"); // 将html代码读取到html字符串中
    
            try {
                Document document = new Document();
                PdfWriter mPdfWriter = PdfWriter.getInstance(document, new FileOutputStream(new File("C:\data\3.pdf")));
                document.open();
                ByteArrayInputStream bin = new ByteArrayInputStream(html.getBytes());
                XMLWorkerHelper.getInstance().parseXHtml(mPdfWriter, document, bin, null, new ChinaFontProvide());
                System.out.println("生成完毕");
                document.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static final class ChinaFontProvide implements FontProvider
        {
    
            @Override public boolean isRegistered(String s)
            {
                return false;
            }
    
            @Override public Font getFont(String arg0, String arg1, boolean arg2, float arg3, int arg4, BaseColor arg5)
            {
                BaseFont bfChinese = null;
                try
                {
                    bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                }
                Font FontChinese = new Font(bfChinese, 12, Font.NORMAL);
                return FontChinese;
            }
        }

    另附PDFKit.java工具类

    public static String readFileByUrl(String urlStr) {
            String res=null;
            try {
                URL url = new URL(urlStr);
                HttpURLConnection conn = (HttpURLConnection)url.openConnection();
                //设置超时间为3秒
                conn.setConnectTimeout(3*1000);
                //防止屏蔽程序抓取而返回403错误
                conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                //得到输入流
                InputStream inputStream = conn.getInputStream();
                res = readInputStream(inputStream);
            } catch (Exception e) {
                log.error("通过url地址获取文本内容失败 Exception:" + e);
            }
            return res;
        }
    
        /**
         * 从输入流中获取字符串
         * @param inputStream
         * @return
         * @throws IOException
         */
        public static String readInputStream(InputStream inputStream) throws IOException {
            byte[] buffer = new byte[1024];
            int len = 0;
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            while((len = inputStream.read(buffer)) != -1) {
                bos.write(buffer, 0, len);
            }
            bos.close();
            //System.out.println(new String(bos.toByteArray(),"utf-8"));
            return new String(bos.toByteArray(),"utf-8");
        }

    至此 dpf就可以到下面路径中查看了

    C:\data\3.pdf

    PDF预览

    只需在页面中增加如下代码即可

    <html>
    <head>
        <title>Title</title>
    </head>
    <body>
    <body style="height: 100%;  100%; overflow: hidden; margin: 0px;">
    <embed width="100%" height="100%" src="pdf/3.pdf" type="application/pdf" internalinstanceid="25"/>
    </body>
    </body>
    </html>

    注意:html文档一定是<html>,不可以是<!DOCTYPE html> 不然body的100% 会失去效果

    预览效果

    特别说明

    如上代码生成的pdf,如果直接用工具打开后发现字体是没有问题,但是嵌套在网页后发现字体竟然不是宋体了,下面我们来介绍下IText输出中文的三种字体的选择方式

    1、使用iTextAsian.jar中的字体
        BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.NOT_EMBEDDED);
    2、使用Windows系统字体(TrueType)
            BaseFont.createFont("C:/WINDOWS/Fonts/SIMLI.TTF", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);    
    3、使用资源字体(ClassPath)
        BaseFont.createFont("/SIMYOU.TTF", BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);  //下面着重介绍

    上面是设置字体的方式,刚刚咱们用的第一种方式,所以pdf预览的的时候字体会变,改用下面的方式就没有任何问题了,下面咱们说下标红的是什么意思

    由于项目使用的是springboot,所以发布到liunx后并不能直接从jar中查找相应的字体,要改用ClassPathResource的方式获取,因此更换代码如下:

     ClassPathResource resource = new ClassPathResource("static/STSONG.TTF");
     bfChinese = BaseFont.createFont(resource.getURL().toString(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);

    可将STSONG.TTF直接放入resources文件夹根目录即可

    这样windows和linux都可以正确的生成pdf并预览了。更换后的效果:

     另附:常用字体

    //楷体字
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //方正舒体
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZSTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //方正姚体
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//FZYTK.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //仿宋体
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMFANG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //黑体
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文彩云
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STCAIYUN.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文仿宋
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STFANGSO.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文细黑
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXIHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文新魏
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINWEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文行楷
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STXINGKA.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //华文中宋
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//STZHONGS.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //隶书
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMLI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);//宋体-方正超大字符集
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SURSONG.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    //幼圆
    BaseFont bfComic = BaseFont.createFont("c://windows//fonts//SIMYOU.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);



  • 相关阅读:
    HDOJ1003 MaxSum【逆推】
    HDOJ1698 Just a hook【线段树成段更新lazy标志】武科大ACM暑期集训队选拔赛4题
    HDOJ1102 Constructing Roads【最小生成树】武科大ACM暑期集训队选拔赛1题
    POJ2828 Buy Tickets【线段树,逆序遍历】
    HDOJ1215 ( 七夕节 )【居然还可以这么解~】
    HDOJ1089HDOJ1096【格式练习】
    HDOJ1233 ( 还是畅通工程 ) 【最小生成树,kruscal】
    HDOJ1035 ( Robot Motion ) 【递归】
    POJ3468 A Simple Problem with Integers【线段树 成段更新+求和 lazy标志】
    HDOJ1216 Assistance Required【打表】武科大ACM暑期集训队选拔赛7题
  • 原文地址:https://www.cnblogs.com/blueskyli/p/9921832.html
Copyright © 2020-2023  润新知