iText 用 HTMLWorker 转换 HTML 为 PDF 时可设置表格列宽度
生成 pdf 的方式有多种,直接用 iText 编码控制产生,fop 转换,不过我觉得很方便的一种方法就是用 iText 的 HTMLWorker 类直接把 HTML 转换成相应的 PDF 文档,HTMLWorker 可支持图片和表格,一定数量的样式控制。这样可以让我们关注到 HTML 页面设计上,至于转换出来的效果就要看母版 HTML 的设计功底了。要知道这个 HTML 中的样式要让 HTMLWorker 可理解的,并非说能支持 CSS2 还是 CSS3。HTMLWorker 能支持的样式还是非常有限,并且还未文档化的,有些多试试,能看看源代码是自然可以让胸中更有数了。
项目中有一个比较迫切的问题是把 HTML 中的表格转换成 PDF 的 PdfPTable 时,无论是在 <td> 上用 width="xxx" 或是 style="width:xxx" 时都看不到宽度的设置效果,iText 总是让生成的 PdfPTable 平均分配单元格宽度的。这对于单元格宽度有过于悬殊的需求是无法妥协的,所以要一种办法来支持自定义单元格宽度,让 width="xxx" 或是 style="width:xxx" 有一种控制能力就行。又得改源代码了,网上找到了是支持 iText 2.1.7 的改法,本篇是针对 iText 5.0.4 的做法,使支持 width="10%" 百分比来控制单元格宽度。
需要改动的文件有三个,全是在包 com.itextpdf.text.html.simpleparser 中的,HTMLWorker.java、IncTable.java 和 IncCell.java。我把改动的地方用 diff 生成的 patch 文件列出来吧,可以照着改,或是直接 patch。后面修改后的代码还提供下载,把类放在自己项目中的 src 目录中即可,想拉进原来的 iText.jar 包亦可。
HTMLWorker.java.patch:
IncTable.java.patch
IncCell.java.patch
注意下,这是针对 iText 5.0.4 的版本,其他的版本可能有差异,打完补丁后给 <td width="10%"> 设置这样的百分比宽度就可以在 PDF 中看到效果的。 注意,你可以只给第一个 <tr> 下的每一个 <td> 设置宽度,用百分比的。而且必须是第一行中每个 <td> 都要 width 属性。如果在 <tr> 中某个 <td> 设置了 width 属性,其他的 <td> 也必须要,不然会出现空指针错误。
这里是修改后的上面三个完整源程序的下载:HTMLWorkerTablePatch.zip。
参考:1. Re: HTMLWorker - table cell width 永久链接 https://yanbin.blog/itext-htmlworker-html2pdf-table-cellwidth/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
项目中有一个比较迫切的问题是把 HTML 中的表格转换成 PDF 的 PdfPTable 时,无论是在 <td> 上用 width="xxx" 或是 style="width:xxx" 时都看不到宽度的设置效果,iText 总是让生成的 PdfPTable 平均分配单元格宽度的。这对于单元格宽度有过于悬殊的需求是无法妥协的,所以要一种办法来支持自定义单元格宽度,让 width="xxx" 或是 style="width:xxx" 有一种控制能力就行。又得改源代码了,网上找到了是支持 iText 2.1.7 的改法,本篇是针对 iText 5.0.4 的做法,使支持 width="10%" 百分比来控制单元格宽度。
需要改动的文件有三个,全是在包 com.itextpdf.text.html.simpleparser 中的,HTMLWorker.java、IncTable.java 和 IncCell.java。我把改动的地方用 diff 生成的 patch 文件列出来吧,可以照着改,或是直接 patch。后面修改后的代码还提供下载,把类放在自己项目中的 src 目录中即可,想拉进原来的 iText.jar 包亦可。
HTMLWorker.java.patch:
150d49
2< import java.util.Collections;
3586d584
4< ArrayList<Integer> cellWidths = new ArrayList<Integer>();
5591,598c589
6< //cells.add(((IncCell) obj).getCell());
7< IncCell cell = (IncCell)obj;
8< if(cell.getWidth() != null){
9< cellWidths.add(cell.getWidth());
10< }
11<
12< cells.add(cell.getCell());
13<
14---
15> cells.add(((IncCell) obj).getCell());
16606,613d596
17< if(cellWidths.size()>0){
18< Collections.reverse(cellWidths);
19< int[] widths = new int[cellWidths.size()];
20< for(int i=0;i<widths.length;i++){
21< widths[i] = cellWidths.get(i).intValue();
22< table.setColWidths(widths);
23< }
24< }
IncTable.java.patch
149d48
2< import java.util.List;
351d49
4< import com.itextpdf.text.DocumentException;
566,67d63
6< private int[] colWidths;
7<
898,105d93
9< public int[] getColWidths(){
10< return colWidths;
11< }
12<
13< public void setColWidths(int[] colWidths){
14< this.colWidths = colWidths;
15< }
16<
17130,136d117
18< try{
19< if(colWidths != null){
20< table.setWidths(colWidths);
21< }
22< }catch(DocumentException e){
23< e.printStackTrace();
24< }
IncCell.java.patch
163d62
2< private Integer width;
3106,109d104
4< value = props.getProperty("width");
5< if(value != null && value.endsWith("%")){
6< width = new Integer(value.replace("%",""));
7< }
8148,155d142
9<
10< public Integer getWidth(){
11< return width;
12< }
13<
14< public void setWidth(Integer width){
15< this.width = width;
16< }
注意下,这是针对 iText 5.0.4 的版本,其他的版本可能有差异,打完补丁后给 <td width="10%"> 设置这样的百分比宽度就可以在 PDF 中看到效果的。 注意,你可以只给第一个 <tr> 下的每一个 <td> 设置宽度,用百分比的。而且必须是第一行中每个 <td> 都要 width 属性。如果在 <tr> 中某个 <td> 设置了 width 属性,其他的 <td> 也必须要,不然会出现空指针错误。
这里是修改后的上面三个完整源程序的下载:HTMLWorkerTablePatch.zip。
参考:1. Re: HTMLWorker - table cell width 永久链接 https://yanbin.blog/itext-htmlworker-html2pdf-table-cellwidth/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。