返回顶部
首页 > 资讯 > 后端开发 > JAVA >html转pdf(总结五种方法Java)
  • 108
分享到

html转pdf(总结五种方法Java)

javahtmlpdf 2023-08-31 17:08:27 108人浏览 安东尼
摘要

html转pdf(总结五种方法Java) Java 实现html转pdf,总结五种方法。 推荐使用wkhtmltopdf,Itext 方法一:使用wkhtmltopdf 1、下载插件wkhtmlto

htmlpdf总结五种方法Java)

Java 实现html转pdf,总结五种方法。
推荐使用wkhtmltopdf,Itext
(img-M4kXdzcT-1669887116934)(_v_images/20221201165346879_22464.png)]

方法一:使用wkhtmltopdf

1、下载插件wkhtmltopdf
https://wkhtmltopdf.org/downloads.html(img-lzLsty7k-1669887116935)(_v_images/20221201163606556_16343.png)]

2、本机测试
本目录下cmd进入
输入命令 wkhtmltopdf.exe ‪E:\学习文档\百度常用标签.html ‪E:\学习文档\百度常用标签.pdf
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fPVH6Enr-1669887116935)(_v_images/20221201164132812_15695.png)]

3、java代码实现
HtmlToPdf类

import java.io.File; public class HtmlToPdf {     //    wkhtmltopdf在系统中的路径    private static final String toPdfTool = "‪D:\\wkhtmltopdf\\bin\\wkhtmltopdf.exe";         public static boolean convert(String srcPath, String destPath,String toPdfTool){        File file = new File(destPath);        File parent = file.getParentFile();        //如果pdf保存路径不存在,则创建路径        if(!parent.exists()){            parent.mkdirs();        }        StringBuilder cmd = new StringBuilder();        cmd.append(toPdfTool);        cmd.append(" ");        cmd.append(" --header-line");//页眉下面的线        cmd.append(" --margin-top 3cm ");//设置页面上边距 (default 10mm)        // cmd.append(" --header-html file:///"+WEBUtil.getServletContext().getRealPath("")+FileUtil.convertSystemFilePath("\\style\\pdf\\head.html"));// (添加一个HTML页眉,后面是网址)        cmd.append(" --header-spacing 5 ");// (设置页眉和内容的距离,默认0)        //cmd.append(" --footer-center (设置在中心位置的页脚内容)");//设置在中心位置的页脚内容        //cmd.append(" --footer-html file:///"+WebUtil.getServletContext().getRealPath("")+FileUtil.convertSystemFilePath("\\style\\pdf\\foter.html"));// (添加一个HTML页脚,后面是网址)        cmd.append(" --footer-line");/public class WaterMarkEventHandler implements IEventHandler {        private String waterMarkContent;        private int waterMarkX;        private int waterMarkY;    public WaterMarkEventHandler(String waterMarkContent) {        this(waterMarkContent, 5, 5);    }    public WaterMarkEventHandler(String waterMarkContent, int waterMarkX, int waterMarkY) {        this.waterMarkContent = waterMarkContent;        this.waterMarkX = waterMarkX;        this.waterMarkY = waterMarkY;    }    @Override    public void handleEvent(Event event) {        PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;        PdfDocument document = documentEvent.getDocument();        PdfPage page = documentEvent.getPage();        Rectangle pageSize = page.getPageSize();        PdfFont pdfFont = null;        try {            pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);        } catch (IOException e) {            e.printStackTrace();        }        Pdfcanvas pdfCanvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), document);        Paragraph waterMark = new Paragraph(waterMarkContent).setOpacity(0.5f);        Canvas canvas = new Canvas(pdfCanvas, pageSize)            .setFontColor(WebColors.getRGBColor("lightgray"))            .setFontSize(16)            .setFont(pdfFont);        for (int i = 0; i < waterMarkX; i++) {            for (int j = 0; j < waterMarkY; j++) {                canvas.showTextAligned(waterMark, (150 + i * 300), (160 + j * 150), document.getNumberOfPages(), TextAlignment.CENTER, VerticalAlignment.BOTTOM, 120);            }        }        canvas.close();    }}
public class PageEventHandler implements IEventHandler {    @Override    public void handleEvent(Event event) {        PdfDocumentEvent documentEvent = (PdfDocumentEvent) event;        PdfDocument document = documentEvent.getDocument();        PdfPage page = documentEvent.getPage();        Rectangle pageSize = page.getPageSize();        PdfFont pdfFont = null;        try {            pdfFont = PdfFontFactory.createFont("STSongStd-Light", "UniGB-UCS2-H", false);        } catch (IOException e) {            e.printStackTrace();        }        PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), document);        Canvas canvas = new Canvas(pdfCanvas, pageSize);        float  x = (pageSize.getLeft() + pageSize.getRight()) / 2;        float  y = pageSize.getBottom() + 15;        Paragraph paragraph = new Paragraph("第" + document.getPageNumber(page) + "页/共" + document.getNumberOfPages() + "页")            .setFontSize(10)            .setFont(pdfFont);        canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);        canvas.close();    }}

3、转换工具类

@Slf4jpublic class HtmlToPdfUtils {        public static void convertToPdf(InputStream inputStream, String waterMark, String fontPath, OutputStream outputStream) throws IOException {        PdfWriter pdfWriter = new PdfWriter(outputStream);        PdfDocument pdfDocument = new PdfDocument(pdfWriter);        //设置为A4大小        pdfDocument.setDefaultPageSize(PageSize.A4);        //添加水印        pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new WaterMarkEventHandler(waterMark));        //添加中文字体支持        ConverterProperties properties = new ConverterProperties();        FontProvider fontProvider = new FontProvider();        //        设置字体                //添加自定义字体,例如微软雅黑        if (StringUtils.isNotBlank(fontPath)) {            PdfFont microsoft = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H, false);            fontProvider.addFont(microsoft.getFontProgram(), PdfEncodings.IDENTITY_H);        }        properties.setFontProvider(fontProvider);        //        读取Html文件流,查找出当中的 或出现类似的符号空格字符        inputStream = readInputStrem(inputStream);        if (inputStream != null) {            //        生成pdf文档            HtmlConverter.convertToPdf(inputStream, pdfDocument, properties);            pdfWriter.close();            pdfDocument.close();            return;        } else {            log.error("转换失败!");        }    }        private static InputStream readInputStrem(InputStream inputStream) {        // 定义一些特殊字符的正则表达式 如:        String regEx_special = "\\&[a-zA-Z]{1,10};";        try {            //<1>创建字节数组输出流,用来输出读取到的内容            ByteArrayOutputStream baos = new ByteArrayOutputStream();            //<2>创建缓存大小            byte[] buffer = new byte[1024]; // 1KB            //每次读取到内容的长度            int len = -1;            //<3>开始读取输入流中的内容            while ((len = inputStream.read(buffer)) != -1) { //当等于-1说明没有数据可以读取了                baos.write(buffer, 0, len);   //把读取到的内容写到输出流中            }            //<4> 把字节数组转换为字符串            String content = baos.toString();            //<5>关闭输入流和输出流            //            inputStream.close();            baos.close();            //            log.info("读取的内容:{}", content);            //            判断HTML内容是否具有HTML的特殊字符标记            Pattern compile = Pattern.compile(regEx_special, Pattern.CASE_INSENSITIVE);            Matcher matcher = compile.matcher(content);            String replaceAll = matcher.replaceAll("");            //            log.info("替换后的内容:{}", replaceAll);            //            将字符串转化为输入流返回            InputStream stringStream = getStringStream(replaceAll);            //<6>返回结果            return stringStream;        } catch (Exception e) {            e.printStackTrace();            log.error("错误信息:{}", e.getMessage());            return null;        }    }        public static InputStream getStringStream(String sInputString) {        if (sInputString != null && !sInputString.trim().equals("")) {            try {                ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());                return tInputStringStream;            } catch (Exception e) {                e.printStackTrace();            }        }        return null;    }}

4、测试

@Slf4jpublic class Test {    public static void main(String[] args) throws IOException {        long startTime = System.currentTimeMillis();        //       html文件所在相对路径        String htmlFile = "src/main/resources/html/index2.html";        //       pdf文件存储相对路径        String pdfFile = "src/main/resources/x6.pdf";        //        自定义水印        String waterMarkText =  "";        InputStream inputStream = new FileInputStream(htmlFile);        OutputStream outputStream = new FileOutputStream(pdfFile);        //微软雅黑在windows系统里的位置如下,linux系统直接拷贝该文件放在linux目录下即可        //        String fontPath = "src/main/resources/font/STHeiti Light.ttc,0";        String fontPath = "src/main/resources/font/simsun.ttc,0";        HtmlToPdfUtils.convertToPdf(inputStream, waterMarkText, fontPath, outputStream);        log.info("转换结束,耗时:{}ms",System.currentTimeMillis()-startTime);    }}

注意事项

  • 页面中不能出现html的特殊字符标记,如 等(代码中已经处理,所有都替换为空)可忽略
  • 页面中的图片路径,必须是在项目根路径后面的所有地址(相对路径)
  • 页面中的标签要符合规范,必须都具有结束标签等

方法三:使用Spire.Doc

将文档从一种格式转换为另一种格式是Spire.Doc的主要功能之一。这种转换只不过是加载和保存操作的组合。因此,使用Spire.DOC可以将文档从任何受支持的加载格式转换为任何受支持的保存格式。spire.doc分为商业版和免费版,免费版只支持转换前3页,以免费版为例

1、增加一个maven仓库路径

            com.e-iceblue        Http://repo.e-iceblue.cn/repository/Maven-public/    

依赖

    e-iceblue    spire.doc.free    3.9.0

2、转换工具类

public class Html3Pdf {    public static void main(String[] args) throws IOException {    }        public void  spireDoc(String inputHtml,String pdfName) throws IOException {        inputHtml = "src/main/resources/html/index2.html";        //新建Document对象        Document doc = new Document();        //添加section        Section sec = doc.addSection();//        将html转化为流字符串        String htmlText = readTextFromFile(inputHtml);        //添加段落并写入HTML文本        sec.addParagraph().appendHTML(htmlText);        pdfName = "src/main/resources/x4.pdf";        //将文档另存为PDF        doc.saveToFile(pdfName, FileFORMat.PDF);        doc.dispose();    }        public static String readTextFromFile(String fileName) throws IOException {        StringBuffer sb = new StringBuffer();        BufferedReader br = new BufferedReader(new FileReader(fileName));        String content;        while ((content = br.readLine()) != null) {            sb.append(content);        }        return sb.toString();    }}

可参考:https://blog.csdn.net/csdnerM/article/details/120649237

方法四:使用Flying Sauser(技术老旧,对样式不支持)

Flying Sauser实现html2pdf,纠错能力差,支持中文、支持简单的页面和样式,开源
对html代码要求很严格。极易出现中文乱码问题

实现:

public class Html2Pdf {          public static void parsePdf(String content, String storagePath) {         FileOutputStream os = null;         try {             File file = new File(storagePath);             if(!file.exists()) {                 file.createNewFile();             }             os = new FileOutputStream(file);               ITextRenderer renderer = new ITextRenderer(); //解决中文支持问题 //            ITextFontResolver resolver = renderer.getFontResolver(); //            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); //            resolver.addFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);             renderer.setDocumentFromString(content); // 解决图片的相对路径问题,图片路径必须以file开头 // renderer.getSharedContext().setBaseURL("file:/");             renderer.layout();             renderer.createPDF(os);           } catch (DocumentException e) {             e.printStackTrace();         } catch (IOException e) {             e.printStackTrace();         }finally {             if(null != os) {                 try {                     os.close();                 } catch (IOException e) {                     e.printStackTrace();                 }             }         }     }            public static void main(String[] args) throws IOException {         String htmlFilePath = "";         htmlFilePath = "F:/pdf/IText实现对PDF文档属性的基本设置 - 半亩池光 - 博客园.html";         StringBuilder content = new StringBuilder();         BufferedInputStream in;         byte[] bys = new byte[1024];         int len;         in = new BufferedInputStream(new FileInputStream(htmlFilePath));         while ((len = in.read(bys)) != -1) {             content.append(new String(bys, 0, len));         }         String html = closeHTML(content.toString());         html = html.replace(" "," ");           parsePdf(html,"F:/pdf/wahaha.pdf");       }       public static String closeHTML(String str){         List arrTags = new ArrayList();         arrTags.add("br");         arrTags.add("hr");         arrTags.add("link");         arrTags.add("meta");         arrTags.add("img");         arrTags.add("input");         for(int i=0;i=0){                     int tagEnd = str.indexOf(">",tagStart);                     j = tagEnd;                     String preCloseTag = str.substring(tagEnd-1,tagEnd);                     if(!"/".equals(preCloseTag)){                         String preStr = str.substring(0,tagEnd);                         String afterStr = str.substring(tagEnd);                         str = preStr + "/" + afterStr;                     }                 }else{                     break;                 }             }         }         return str;     }   }

方法五:使用PD4ML(样式有问题)

PD4ML是纯Java的类库,使用HTML、CSS作为页面布局和内容定义格式来生成PDF文档的强大工具,可以简化最终用户生成PDF的工作。参考网站:http://www.pd4ml.com
可参考:https://GitHub.com/linkamnal/Html2Pdf
工具类:

public class HtmlToPDFUtil {     public static void main(String[] args) throws Exception {         //HtmlToPDFUtil htmlToPDFUtil = new HtmlToPDFUtil();         HtmlToPDFUtil.generatePDF_2(new File("F:\pdf/demo_ch_pd4ml.pdf"),                 "F:\pdf/flying saucer 使用中的一些问题 (java导出pdf) - 真的勇士,敢于直面这扯淡的人生 - ITeye博客.htm");           //File pdfFile = new File("D:/Test/test3.pdf"); //        String pdfPath = "D:/Test1/mmt"; // //        File file = new File(pdfPath); //        if (!file.exists()) { //            file.mkdirs(); //        } //        String pdfName = "aa.pdf"; //        File pdfFile = new File(pdfPath+File.separator+pdfName); //        StringBuffer html = new StringBuffer(); //        html.append("") //                .append("") //                .append("") //                .append("").append("") //                //.append("") //                .append("") //                .append("显示中文aaaaaaaaaa") //                .append("").append(""); //        StringReader strReader = new StringReader(html.toString()); //        HtmlToPDFUtil.generatePDF_1(pdfFile, strReader);       }       // 手动构造HTML代码     public static void generatePDF_1(File outputPDFFile, StringReader strReader)             throws Exception {         FileOutputStream fos = new FileOutputStream(outputPDFFile);         PD4ML pd4ml = new PD4ML();         pd4ml.setPageInsets(new Insets(20, 10, 10, 10));         pd4ml.setHtmlWidth(950);         pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));         pd4ml.useTTF("java:fonts", true);                 //pd4ml.setDefaultTTFs("KaiTi_GB2312", "KaiTi_GB2312", "KaiTi_GB2312");         pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");         pd4ml.enableDebugInfo();         pd4ml.render(strReader, fos);     }       // HTML代码来自于HTML文件     public static void generatePDF_2(File outputPDFFile, String inputHTMLFileName)             throws Exception {         FileOutputStream fos = new FileOutputStream(outputPDFFile);         PD4ML pd4ml = new PD4ML();         pd4ml.setPageInsets(new Insets(20, 10, 10, 10));         pd4ml.setHtmlWidth(950);         pd4ml.setPageSize(pd4ml.changePageOrientation(PD4Constants.A4));           pd4ml.useTTF("java:fonts", true);         pd4ml.setDefaultTTFs("KaiTi", "KaiTi", "KaiTi");         pd4ml.enableDebugInfo();         pd4ml.render("file:" + inputHTMLFileName, fos);     }   }

来源地址:https://blog.csdn.net/weixin_43981813/article/details/128135730

--结束END--

本文标题: html转pdf(总结五种方法Java)

本文链接: https://lsjlt.com/news/386366.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作