利用itext通过html生成pdf自动添加表头

中文字体篇

首先不管你是纯代码写还是基于HTML转PDF,中文问题一直是一个问题。实际上不用像很多网站上以前给出的要修改源码咯或者引入一些汉字支持的jar包咯巴拉巴拉的。很简单,你下载一个字体,或者使用系统内置的中文字体也可以,只需要new一个中文字体即可:

    BaseFont baseCnFont = BaseFont.createFont("/yourFontDir/yourFont.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    Font cnFont = new Font(baseCnFont,fontSize,fontStyle,color);

如果想直接使用系统字体,路径直接指向系统自带的路径文件夹。
若出现*`Font '/yourFontDir/yourFont.ttf' with 'Identity-H' is not recognized`*这样的异常,请尝试在你的字体文件路径后面加上“**`,1`**”,即:

    BaseFont.createFont("/yourFontDir/yourFont.ttf,1",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);


HTML转PDF篇

以前都是直接纯代码生成PDF,后来因为老板各种不定时改需求该样式,于是就开始转为使用HTML转PDF。随着itext的更新迭代,HTML转PDF一样的也变得简单了,你只需要额外引入一个xmlworker的jar包,如果你使用的是maven,那么你只需要添加:

    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>itextpdf</artifactId>
        <version>x.x.x</version>
    </dependency>
    <dependency>
        <groupId>com.itextpdf.tool</groupId>
        <artifactId>xmlworker</artifactId>
        <version>x.x.x</version>
    </dependency>

然后直接上干货吧:

    //定义一系列你网站上需要用到的字体文件,如果不需要的话定义一个中文字体文件即可
    BaseFont baseCnFont = BaseFont.createFont("/yourFontDir/baseCnFont.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    BaseFont cnF1 = BaseFont.createFont("/yourFontDir/font1.otf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    BaseFont cnF2 = BaseFont.createFont("/yourFontDir/font2.otc",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    BaseFont cnF3 = BaseFont.createFont("/yourFontDir/font3.ttf",BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
    
    Document doc = new Document(PageSize.A4);
    //如果是web做下载,后面的传入response的输出流,同时需要设置response的ContentType以及指定Content-Disposition为attachment同时设定fileName,fileName记得URLEncoder
    PdfWriter writer = PdfWriter.getInstance(doc,new FileOutputStream("/yourPDFoutputDir/demo.pdf"));
    //设置页面边距
    doc.setMargins(20, 20, 20, 20);
    doc.open();
    //这里可以代码创建pdf的部分页面(如更加精细的封面等)
    //......
    //设置HTML转PDF时页面边距(建议放在open方法前面,如果不放在open方法前面则必须后面加上newPage才能生效)
    // doc.setMargins(20, 20, 20, 20);
    // doc.newPage();
    XMLWorkerHelper.getInstance().parseXHtml(writer, doc, new ByteArrayInputStream("HTML字符串,我个人是使用的第三方模板工具(如Beetl)直接读取HTML模板,然后填充数据生成HTML字符串".getBytes("UTF-8")),Charset.forName("UTF-8"),new FontProvider() {
        @Override
        public boolean isRegistered(String arg0) {
            return false;
        }
        @Override
        public Font getFont(String fontFamily, String charset, boolean arg2, float size, int style, BaseColor color) {
            //根据CSS中不同的字体名返回不同的字体实例
            if("cssFontName1".equalsIgnoreCase(fontFamily)){
                return new Font(cnF1,size,style,color);
            }else if("cssFontName2".equalsIgnoreCase(fontFamily)){
                return new Font(cnF2,size,style,color);
            }else if("cssFontName3".equalsIgnoreCase(fontFamily)){
                return new Font(cnF3,size,style,color);
            }else{
                //默认字体
                return new Font(baseCnFont,size,style,color);
            }
        }
    });
    doc.close();

需要注意的是itext对需要转成PDF的HTML要求非常严格,标签必须闭合,而且支持的CSS不多,有效效果可能需要有一定的HTML布局和CSS技巧才能实现。
如果仔细度过那个超入门的朋友会知道设置表头有一个固定表头的功能,比如表格很长的时候PDF自动分页了,原生代码可以做到每一页都显示表头。实际上看了下iText的源码发现HTML转PDF的时候也是可以的,iText支持一个CSS属性,只需要给你需要重复表头表尾的table标签设置css属性“repeat-header:yes”或“repeat-footer:yes”即可,然后将你需要重复的表头放在thead标签内,表尾放在tfoot标签内。例:

    <table style="repeat-header:yes;repeat-footer:yes;">
        <thead>
            <tr>
                <th>如果表格过长自动分页了,我是重复的表头1</th>
            </tr>
            <tr>
                <th>如果表格过长自动分页了,我是重复的表头2</th>
            </tr>
        </thead>
        <tbody>
            <tr>
                <td>内容....</td>
            </tr>
            <!--  .....  -->
            <tr>
                <td>内容....</td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <th>如果表格过长自动分页了,我是重复的表尾1</th>
            </tr>
            <tr>
                <th>如果表格过长自动分页了,我是重复的表尾2</th>
            </tr>
        </tfoot>
    </table>

使用代码写pdf的时候,如果某个小章节完毕了,我们需要另起一页直接new Page()即可。在HTML生成pdf的时候也是有特殊的css属性来控制的,分别是page-break-after:alwayspage-break-before:always还有一个page-break-inside属性,但测试没发现有什么特殊的效果

<span style="page-break-after:always;">这段文字后面会重新分页</span>
<p>正常的文字流,但是因为前面元素强制在后面分页了,后面的文字也强制在前面分页了,因此这段文字会是顶头文字,也是这一页的唯一的文字。</p>
<span style="page-break-before:always;">这段文字前面会重新分页</span>

消除表格边框默认的间距则设置table的css添加:“border-collapse:collapse”,然后再分别给table和td、th设置border,如果嫌边框太粗,可将边框宽度设置为小数,如0.3px


本文地址:http://darren.ink/archives/67

 

 

 

总结:

<table repeat-header:yes; ">
<thead>
    <tr>
    </tr>
</thead>
</table>

 

就可以重复表头了

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
iText是一个用于生成PDF文档的开源Java库,它提供了丰富的API和功能,可以通过编程方式创建、编辑和操作PDF文档。iText可以将HTML换为PDF,以便在应用程序中生成具有复杂布局和样式的PDF文档。 要使用iTextHTML换为PDF,你需要遵循以下步骤: 1. 导入iText库:首先,你需要将iText添加到你的Java项目中。你可以从iText官方网站下载最新版本的库文件,并将其添加到你的项目依赖中。 2. 创建PDF文档对象:使用iText库中的PdfDocument类创建一个新的PDF文档对象。 3. 创建HTML解析器:使用iText库中的HtmlConverter类创建一个HTML解析器对象。 4. 将HTML换为PDF:使用HTML解析器对象的convertToPdf()方法,将HTML内容换为PDF格式,并将其添加PDF文档对象中。 5. 保存PDF文档:使用PDF文档对象的close()方法保存并关闭PDF文档。 下面是一个简单的示例代码,演示了如何使用iTextHTML换为PDF: ```java import com.itextpdf.html2pdf.HtmlConverter; import com.itextpdf.kernel.pdf.PdfDocument; import com.itextpdf.kernel.pdf.PdfWriter; public class HtmlToPdfConverter { public static void main(String[] args) { // 创建PDF文档对象 PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output.pdf")); try { // 创建HTML解析器 HtmlConverter.convertToPdf("<html><body><h1>Hello, iText!</h1></body></html>", pdfDoc); // 保存PDF文档 pdfDoc.close(); } catch (Exception e) { e.printStackTrace(); } } } ``` 这是一个简单的示例,将一个包含标题的HTML换为PDF,并将其保存为名为"output.pdf"的文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值