使用pd4ml 将html转换为pdf

本文介绍了使用pd4ml将html转换为pdf时遇到的中文支持问题,包括字体jar包的修改和pd4ml pro版本对中文的支持。对比了pd4ml与itext在转换速度、纠错能力和中文字体支持上的差异。并提供了部分代码示例和pom.xml配置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用pd4ml 将html转换为pdf 遇到的几个问题,总结一下,与大家共享一下:

1 网上自带的fonts.jar不支持中文,加载进去中文乱码 , 需要修改fonts.jar,为此本人已修改好所需要的jar包(支持宋体中文simsun.ttc),链接在这。

2 pd4ml.jar,官方声明,只有pro版本支持中文,这个就比较坑了,并且带demo的在转换成PDF会有水印。


优缺点:

pd4ml相比itext,速度快,纠错能力强,支持多种中文字体,但是是商业。

IText实现html2pdf,速度快,纠错能力差(对Css,标签样式要求很高,标签不闭合都无转换),支持中文(要求HTML使用unicode编码),但中支持一种中文字体,开源。


上部分代码:

//发送业务数据;

request.setAttribute("techProtocolReview",techProtocolReview == null ? 
new TechProtocolReview() : techProtocolReview);
//转发请求到jsp,返回解析之后的内容而不是输出到浏览器
String html = ServletUtils.forward(request,response
,"/WEB-INF/views/modules/pads/machinedesign/techProtocolReviewTrsfPdfView.jsp");
//System.out.println(html);
StringReader strReader = new StringReader(html);
try {
   HtmlToPdf.byte2File(HtmlToPdf.generatePDF(strReader), "E:/", "test.pdf");
   return new ReponseData.Builder(Constant.SUCCESS_CODE).message("页面转化PDF成功").build();
} catch (IOException e) {
   e.printStackTrace();
      logger.error("页面转PDF失败:",e);
   return new ReponseData.Builder(Constant.SUCCESS_CODE).
message("页面转化PDF失败!失败信息:"+e.getMessage()).build();
}

 

工具类:

附注:

WriteListener在javax.servlet 3.1.0版本中

 

import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class ServletUtils {

    public static String forward(HttpServletRequest request, HttpServletResponse response, String src) {
        try{

            //*  ↓↓↓↓↓重新构造response,修改response中的输出流对象,使其输出到字节数组↓↓↓↓↓  *//*
            final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            final ServletOutputStream servletOuputStream = new ServletOutputStream() {
                @Override
                public void write(int b) throws IOException {
                    byteArrayOutputStream.write(b);
                }

                public boolean isReady() {
                    return false;
                }

                public void setWriteListener(WriteListener writeListener) {
                }
            };

            final PrintWriter printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream, "UTF-8"));

            response = new HttpServletResponseWrapper(response) {
                public ServletOutputStream getOutputStream() {
                    return servletOuputStream;
                }
                public PrintWriter getWriter() {
                    return printWriter;
                }
            };
             //*  ↑↑↑↑↑↑重新构造response,修改response中的输出流对象,使其输出到字节数组↑↑↑↑↑↑ *//*

            //执行forward操作
            request.getRequestDispatcher(src).forward(request,response);

            //把字节流中的内容太转为字符串
            return new String(byteArrayOutputStream.toByteArray(),"utf-8");
        }
        catch (Exception e){
            throw new RuntimeException(e);
        }
    }
}

 

import org.apache.log4j.Logger;
import org.zefer.pd4ml.PD4Constants;
import org.zefer.pd4ml.PD4ML;
import java.awt.Insets;
import java.io.*;




public class HtmlToPdf {

    private static final Logger LOG = Logger.getLogger(HtmlToPdf.class);

    public static byte[] generatePDF( StringReader strReader) throws IOException {
            //FileOutputStream fos = new FileOutputStream(outputPDFFile);
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            PD4ML pd4ml = new PD4ML();
            pd4ml.setPageInsets(new Insets(5, 5, 5, 5));
            pd4ml.setHtmlWidth(900);
            pd4ml.setPageSize(PD4Constants.A4);  // A4竖向显示  pd4ml.changePageOrientation(PD4Constants.A4)横向显示
            //fonts.jar的配置文件中的值,用于中文乱码
            pd4ml.useTTF("java:fonts", true);
            pd4ml.setDefaultTTFs("SimSun", "SimSun", "SimSun");
            pd4ml.enableDebugInfo();
            pd4ml.render(strReader, os);  //如果用上面的fos,就是写出到指定的文件
            return os.toByteArray();

    }
    /**
     * 根据byte数组,生成文件
     * @param bfile 文件数组
     * @param filePath 文件存放路径
     * @param fileName 文件名称
     */
    public static void byte2File(byte[] bfile,String filePath,String fileName) throws IOException {
        BufferedOutputStream bos=null;
        FileOutputStream fos=null;
        File file=null;

            File dir=new File(filePath);
            if(!dir.exists() && !dir.isDirectory()){//判断文件目录是否存在
                dir.mkdirs();
            }
            file=new File(filePath+fileName);
            fos=new FileOutputStream(file);
            bos=new BufferedOutputStream(fos);
            bos.write(bfile);
            //FileUtils.downFile(file, request, response);

                if(bos != null){
                    bos.close();
                }
                if(fos != null){
                    fos.close();
                }

    }

}  

相应的pom.xml:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值