利用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
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
iText 是一个开源的 Java PDF 库,可以用来创建、操作和处理 PDF 文件。以下是基于 iText 生成 PDF 文件的简单示例: 1. 添加 iText 依赖 在项目的 pom.xml 文件中添加如下依赖: ```xml <dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version> </dependency> ``` 2. 创建 PDF 文件 使用 iText 创建 PDF 文件的步骤如下: ```java // 创建 PDF 文档对象 Document document = new Document(); // 创建 PDF 输出流 PdfWriter.getInstance(document, new FileOutputStream("output.pdf")); // 打开文档 document.open(); // 添加内容 document.add(new Paragraph("Hello, World!")); // 关闭文档 document.close(); ``` 在上面的代码中,首先创建了一个 Document 对象,然后使用 PdfWriter 创建一个 PDF 输出流,将输出流与 Document 对象关联。接下来打开文档,添加内容,最后关闭文档。 3. 添加表格和图片 除了文本,iText 还支持添加表格和图片等元素。以下是添加表格和图片的示例代码: ```java // 创建 PDF 文档对象 Document document = new Document(); // 创建 PDF 输出流 PdfWriter.getInstance(document, new FileOutputStream("output.pdf")); // 打开文档 document.open(); // 添加表格 PdfPTable table = new PdfPTable(3); table.addCell("Name"); table.addCell("Age"); table.addCell("Gender"); table.addCell("John Doe"); table.addCell("30"); table.addCell("Male"); document.add(table); // 添加图片 Image image = Image.getInstance("image.png"); document.add(image); // 关闭文档 document.close(); ``` 在上面的代码中,首先创建了一个 PdfPTable 对象,添加表头和数据,然后将表格添加PDF 文档中。接下来添加了一张图片,最后关闭文档。 以上是基于 iText 生成 PDF 文件的简单示例,iText 还支持更丰富的 PDF 操作,如添加书签、水印、表单等功能。详细的示例可以参考 iText 官方文档。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值