Itext 导出PDF(中文解决,HTML转PDF)

iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 iText的安装非常方便,下载iText.jar文件后,只需要在系统的CLASSPATH中加入iText.jar的路径,在程序中就可以使用iText类库了。


目前项目中需要用到把HTML格式的文本片段,以PDF格式输出下载,现决定采用itext组件来实现。

maven配置:

<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>


代码片段:

public class PdfUtil {

    /**
     * 重写 字符设置方法,解决中文乱码问题
     * 
     */
    public static class MyFontsProvider extends XMLWorkerFontProvider {

        public MyFontsProvider(){
            super(null, null);
        }

        @Override
        public Font getFont(final String fontname, String encoding, float size, final int style) {
            String fntname = fontname;
            if (fntname == null) {
                fntname = "宋体";
            }
            if (size == 0) {
                size = 4;
            }
            return super.getFont(fntname, encoding, size, style);
        }
    }

    private static Logger      logger            = LoggerFactory.getLogger(PdfUtil.class);

    /**
     * PDF生成路径
     */
    public static final String PDF_DOWNLOAD_PATH = "/trialRecord/pdf/";

    /**
     * 导出PDF文件
     * 
     * @param content
     * @param response
     */
    public void exportPdf(String fileName, String content, HttpServletResponse response) {

        FileOutputStream fos = null;
        FileInputStream in = null;
        OutputStream out = null;
        Document document = new Document();
        File newPath = null;
        try {
            if (StringUtils.isBlank(fileName)) {
                fileName = DateUtil.getTodayDateTime().replaceAll(" ", "").replaceAll(":", "").replaceAll("-", "")
                           + "文件名.pdf";
            }
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            String dicPath = new File(".").getCanonicalPath();
            String srcPath = dicPath + PDF_DOWNLOAD_PATH + fileName;

            newPath = new File(dicPath + PDF_DOWNLOAD_PATH);
            newPath.mkdirs();
            // 删除临时文件
            boolean success = fileDelete(newPath);

            if (success) {
                newPath.mkdirs();
                File file = new File(srcPath);
                fos = new FileOutputStream(file);

                PdfWriter writer = PdfWriter.getInstance(document, fos);

                document.open();
                InputStream htmlInput = new ByteArrayInputStream(content.getBytes("UTF-8"));
                // 使用我们的字体提供器,并将其设置为unicode字体样式
                MyFontsProvider fontProvider = new MyFontsProvider();
                fontProvider.addFontSubstitute("lowagie", "garamond");
                fontProvider.setUseUnicode(true);
                CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
                HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
                htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
                XMLWorkerHelper.getInstance().getDefaultCssResolver(true);

                XMLWorkerHelper.getInstance().parseXHtml(writer, document, htmlInput, null, Charset.forName("UTF-8"),
                                                         fontProvider);

                document.close();
                writer.close();
                // 设置文件ContentType类型,这样设置,会自动判断下载文件类型
                response.setContentType("multipart/form-data");
                // 设置响应头,控制浏览器下载该文件
                response.setHeader("content-disposition", "attachment;filename=" + fileName);
                // 读取要下载的文件,保存到文件输入流
                in = new FileInputStream(srcPath);
                // 创建输出流
                out = response.getOutputStream();
                // 创建缓冲区
                byte buffer[] = new byte[1024];
                int len = 0;
                // 循环将输入流中的内容读取到缓冲区当中
                while ((len = in.read(buffer)) > 0) {
                    // 输出缓冲区的内容到浏览器,实现文件下载
                    out.write(buffer, 0, len);
                }
            }
        } catch (DocumentException e) {
            logger.error("Export PDF error :" + e.getMessage());
            throw new RuntimeException("Export PDF error : ", e);
        } catch (IOException e) {
            logger.error("Export PDF error :" + e.getMessage());
            throw new RuntimeException("Export PDF error : ", e);
        } catch (Exception e) {
            logger.error("Export PDF error :" + e.getMessage());
            throw new RuntimeException("Export PDF error : ", e);
        } finally {
            IOUtils.closeQuietly(fos);
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
            if (newPath != null) {
                fileDelete(newPath);
            }
        }
    }

    /**
     * 删除文件
     *
     * @param file
     * @return
     */
    private boolean fileDelete(File file) {
        if (file.isDirectory()) {
            String[] children = file.list();
            // 递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = fileDelete(new File(file, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空,可以删除
        return file.delete();
    }
}


补充说明:在实际使用中,发现以上代码在windows环境中项目可以正常导出中文的PDF文件,但把项目部署到linux环境就又不显示中文了,原因是linux环境中可能没有 相应的 宋体 字体文件


解决办法: 把


        if (fntname == null) {
                fntname = "宋体";
            }           
这部分代码改为  
         if (fntname == null) {
                fntname = "fontFile/simsun.ttf";
            }

其中  simsun.ttf该文件是 宋体的字体文件,如果需要其他字体,则把该文件替换为其他支持linux环境的字体文件即可

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值