目录:
- 概述
- 两种应用场景的实现
[一]、概述
本文演示如何把HTML的内容转为PDF文档,分两种情况:
- 第一种:直接把HTML转成单个PDF文件;
- 第二种:把HTML内容转成PDF的元素(ELement),对应已有的PDF文档,可以把转换后的Element追加到document中,生成PDF文件
[二]、两种应用场景的实现
以我的某一博客:http://www.micmiu.com/os/linux/shell-dev-null/ 的内容生成一个演示的html文件。
demo.html 内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="zh-CN"> <head profile="http://gmpg.org/xfn/11"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>/dev/null 2>&1 详解 | micmiu - 大大的技术 | 小小的生活</title> <link rel="stylesheet" type="text/css" media="all" href="http://www.micmiu.com/wp-content/themes/zbench/style.css" /> <link rel='shortlink' href='http://www.micmiu.com/?p=814' /> </head> <body class="single single-post postid-814 single-format-standard"> <div class="entry"> <p>我们在shell 脚本命令中会经常看到类似这样内容:<span style="color: #ff0000;">/dev/null 2>&1</span>,这条命令的意思是将标准输出和错误输出全部重定向到 /dev/null 空设置中,也就是将产生的所有信息丢弃。</p> <p><span style="color: #0000ff;">[一]、命令的解释</span></p> <p><span style="color: #ff0000;"> >/dev/null 2>&1</span> 可以拆分开易于理解:</p> <ol> <li><span style="line-height: 22px;"><span style="color: #ff0000;">></span> :代表重定向到哪里,例如:echo “micmiu.com” > /home/michaeltest.txt<br /> </span></li> <li><span style="line-height: 22px;"><span style="color: #ff0000;">/dev/null</span> :代表空设备文件<br /> </span></li> <li><span style="line-height: 22px;"><span style="color: #ff0000;">2></span> :表示stderr标准错误<br /> </span></li> <li><span style="line-height: 22px;"><span style="color: #ff0000;">&</span> :表示等同于的意思,2>&1,表示2的输出重定向等同于1<br /> </span></li> <li><span style="line-height: 22px;"><span style="color: #ff0000;">1</span> :表示stdout标准输出,系统默认值是1,所以”>/dev/null”等同于 “1>/dev/null”<br /> </span></li> </ol> <p>故:”>/dev/null 2>&1″ 也可以写成 “1>/dev/null 2>&1″</p> <p><span style="color: #0000ff;">[二]、命令的执行过程</span></p> <p><span style="color: #ff0000;">1>/dev/null</span> :首先表示标准输出重定向到空设备文件,也就是不输出任何信息到终端,说白了就是不显示任何信息。<br /> <span style="color: #ff0000;">2>&1</span> :接着,标准错误输出重定向到标准输出,因为之前标准输出已经重定向到了空设备文件,所以标准错误输出也重定向到空设备文件。</p> <p>本文介绍到此结束@<a href="http://www.micmiu.com/" >Michael Sun</a>.</p> </div> </body> </html> |
demo.html 在浏览器中的效果如下:
实现转PDF的Java代码:Demo4HTMLFile2PDF.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
package com.micmiu.pdf.itext; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import com.itextpdf.text.BaseColor; import com.itextpdf.text.Chapter; import com.itextpdf.text.Chunk; import com.itextpdf.text.Document; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Section; import com.itextpdf.text.WritableDirectElement; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfWriter; import com.itextpdf.text.pdf.draw.LineSeparator; import com.itextpdf.tool.xml.ElementHandler; import com.itextpdf.tool.xml.Writable; import com.itextpdf.tool.xml.XMLWorkerHelper; import com.itextpdf.tool.xml.pipeline.WritableElement; /** * HTML文件转换为PDF * * @author <a href="http://www.micmiu.com">Michael Sun</a> */ public class Demo4HTMLFile2PDF { /** * @param args */ public static void main(String[] args) throws Exception { String htmlFile = "d:/test/itext/demo.html"; // 直接把HTML文件转为PDF文件 String pdfFile = "d:/test/itext/demo-htmlfile.pdf"; Demo4HTMLFile2PDF.parseHTML2PDFFile(pdfFile, new FileInputStream( htmlFile)); // HTML文件转为PDF中的Elements String pdfFile2 = "d:/test/itext/demo-htmlfile2.pdf"; Demo4HTMLFile2PDF.parseHTML2PDFElement(pdfFile2, new FileInputStream( htmlFile)); } /** * 用于HTML直接转换为PDF文件 * * @param fileName * @throws Exception */ public static void parseHTML2PDFFile(String pdfFile, InputStream htmlFileStream) throws Exception { BaseFont bfCN = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false); // 中文字体定义 Font chFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLUE); Font secFont = new Font(bfCN, 12, Font.NORMAL, new BaseColor(0, 204, 255)); Document document = new Document(); PdfWriter pdfwriter = PdfWriter.getInstance(document, new FileOutputStream(pdfFile)); pdfwriter.setViewerPreferences(PdfWriter.HideToolbar); document.open(); int chNum = 1; Chapter chapter = new Chapter(new Paragraph("HTML文件转PDF测试", chFont), chNum++); Section section = chapter.addSection(new Paragraph("/dev/null 2>&1 详解", secFont)); // section.setNumberDepth(2); // section.setBookmarkTitle("基本信息"); section.setIndentation(10); section.setIndentationLeft(10); section.setBookmarkOpen(false); section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT); section.add(Chunk.NEWLINE); document.add(chapter); // html文件 InputStreamReader isr = new InputStreamReader(htmlFileStream, "UTF-8"); // 方法一:默认参数转换 XMLWorkerHelper.getInstance().parseXHtml(pdfwriter, document, isr); // 方法二:可以自定义参数 // HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); // htmlContext.charSet(Charset.forName("UTF-8")); // htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory()); // CSSResolver cssResolver = XMLWorkerHelper.getInstance() // .getDefaultCssResolver(true); // Pipeline<?> pipeline = new CssResolverPipeline(cssResolver, // new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, // pdfwriter))); // XMLWorker worker = new XMLWorker(pipeline, true); // XMLParser p = new XMLParser(); // p.addListener(worker); // // p.parse(isr); // p.flush(); document.close(); } /** * HTML文件转为PDF中的Elements,便于把HTML内容追加到已有的PDF中 * * @param pdfFile * @param htmlFileStream */ public static void parseHTML2PDFElement(String pdfFile, InputStream htmlFileStream) { try { Document document = new Document(PageSize.A4); FileOutputStream outputStream = new FileOutputStream(pdfFile); PdfWriter pdfwriter = PdfWriter.getInstance(document, outputStream); // pdfwriter.setViewerPreferences(PdfWriter.HideToolbar); document.open(); BaseFont bfCN = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", false); // 中文字体定义 Font chFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLUE); Font secFont = new Font(bfCN, 12, Font.NORMAL, new BaseColor(0, 204, 255)); Font textFont = new Font(bfCN, 12, Font.NORMAL, BaseColor.BLACK); int chNum = 1; Chapter chapter = new Chapter(new Paragraph( "HTML文件转PDF元素,便于追加其他内容", chFont), chNum++); Section section = chapter.addSection(new Paragraph( "/dev/null 2>&1 详解", secFont)); section.setIndentation(10); section.setIndentationLeft(10); section.setBookmarkOpen(false); section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT); section.add(Chunk.NEWLINE); final List<Element> pdfeleList = new ArrayList<Element>(); ElementHandler elemH = new ElementHandler() { public void add(final Writable w) { if (w instanceof WritableElement) { pdfeleList.addAll(((WritableElement) w).elements()); } } }; InputStreamReader isr = new InputStreamReader(htmlFileStream, "UTF-8"); XMLWorkerHelper.getInstance().parseXHtml(elemH, isr); List<Element> list = new ArrayList<Element>(); for (Element ele : pdfeleList) { if (ele instanceof LineSeparator || ele instanceof WritableDirectElement) { continue; } list.add(ele); } section.addAll(list); section = chapter.addSection(new Paragraph("继续添加章节", secFont)); section.setIndentation(10); section.setIndentationLeft(10); section.setBookmarkOpen(false); section.setNumberStyle(Section.NUMBERSTYLE_DOTTED_WITHOUT_FINAL_DOT); section.add(new Chunk("测试HTML转为PDF元素,方便追加其他内容", textFont)); document.add(chapter); document.close(); } catch (Exception e) { e.printStackTrace(); } } } |
两种方式转换后生成的PDF效果图如下:
本文介绍到此结束@Michael Sun.
原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
本文链接地址: http://www.micmiu.com/opensource/expdoc/itext-html-pdf/
博主你的代码151行,显示是这样的,尖括号没有显示出来。
final List<Element> pdfeleList
而不是这样的
final List pdfeleList
请问能否把jar包列表及其对应的版本号列出来
你好 请问一下 WritableDirectElement 这个包在哪下呀 我的是itext 5.1.2 还有 tool是在那个包里呀
这个你可以搜索下 xmlwork 这个项目,itext 是基于该项目实现html转pdf的
你好怎么把html中的图片也转换到 pdf 中呢?
xmlwork 本身就支持 img 标签
你好 怎么把HTML 中包含的图片也转换过去呢?
img 标签是支持的 它会读取图片转换的
你好, 我有如下一段HTML 代码:
test font Verdana
中文字体
通过:
InputStreamReader isr = new InputStreamReader(htmlFileStream, “UTF-8”); XMLWorkerHelper.getInstance().parseXHtml(elemH, isr); List list = new ArrayList();
for (Element ele : pdfeleList) 解析后, 发现 list 中不包含图片 element, pdf中无法展现, 所用版本为: 5.4.2, 请帮忙看一下
请问一下 我如果正文中我不想要Chapter的编号怎么办? 甚至我连Chapter 的标题都不想要我该怎么办?大大 请指教啊!
不要chapter 直接去掉相关代码就可以了
你好,近段时间在学习xmlworker,想请教下你,我那里的xmlworker的div border 不能解析出来,也就是生成的div边框显示不出来,不知道你行不行呢?谢谢
我查看了下官方文档 好像 border 的属性不支持
你好,我用到的itext5.4.1 、xmlworker-5.4.1 从html读取中文是空的 英文是可以的,不从html读取是可以的,你上面的例子也是这样的 ,有啥解决办法吗?
5.4.1我没有试过,不过之前有人好像是可以的,xmlworker只支持部分标签,所以你应该把需要的内容解析的出来再转pdf,我的例子应该没有问题
弄好了,版本的不兼容问题,itextpdf-5.4.1.jar不能和xmlworker-1.2.1-micmiu.jar一起工作,我换成xmlworker-5.4.0.jar就可以了,但不能解析中文字符,按照您http://www.micmiu.com/opensource/expdoc/itext-xml-worker-cn/所说的修改源码,就可以了,很感谢。
xmlworker 的版本号变化这么大啊 看来我out了
大神能发一份这个jar包吗?
1021454642@qq.com
你要的是哪个包?解决中文的包?
大神 可以求一个修改源码后的xmlworker-5.4.0.jar吗?我修改了JAR还是一样不可以不知道
终于可以了,将所有的jar都换成最新的,尴尬了
请问我的修改源码后为什么中文还是不能显示呢?
注意软件版本以及中文支持的jar包 是否已经添加到项目中
我用的是itextpdf-5.4.3.jar iTextAsian.jar xmlworker-5.4.3.jar这几个JAR包,我将那两个需要修改的类反编译修改了源码,但再编译成class dos下总是报错,直接将1.2.1那两个文件覆盖5.4.3的也没作用,还是乱码
反编译看看源码大概实现是可以的,如果要重新编译 还是建议在源码的基础上做
大神,我用文本编辑器编辑了一段文字,获得html格式的源码,存在数据库里,如何将这个源码导出成pdf?我直接定义一个String htmlfile = 源码,这种方法不行
应该可以的 这个和获取url 本质是一样的
如何实现自定义导出路径呢?
从你的文章收益很大,解决了中文支持问题。但发现一个问题在html文件中添加table标签怎么程序报错了, 请问这是什么问题?
异常是:Exception in thread “main” java.lang.NoSuchMethodError: com.itextpdf.text.pdf.PdfPTable.addCell(Lcom/itextpdf/text/pdf/PdfPCell;)V
难道是版本有问题吗? 不支持那个方法了? 我用的jar包是 itextpdf-5.4.1.jar 还有您提供的对中文支持的jar包
官方文档中是支持 table 的
请问您这个问题解决了吗?我现在也是遇到同样的问题,不知道是什么原因,求教啊
这个问题解决了吗,到底是怎么回事呀 😳