itext5创建pdf表格及遇到的一些问题

这篇具有很好参考价值的文章主要介绍了itext5创建pdf表格及遇到的一些问题。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0. 核心依赖:
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.10</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
1. 设置页眉图片及下划线

通过PdfPageEventHelper事件可以动态的创建页眉,数据构建出多少页pdf就有多少页页眉

package com.example.pdf;

import com.example.pdf.vo.RenovationDocNameEnum;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

/**
 * 内部类 添加页眉、页脚
 */
public class PdfEvent extends PdfPageEventHelper {

    // 一页加载完成触发,写入页眉和页脚
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
        PdfPTable head = new PdfPTable(1);
        PdfObject businessType = document.getAccessibleAttribute(new PdfName("businessType"));
        PdfObject flag = document.getAccessibleAttribute(new PdfName("flag"));
        try {
            if (RenovationDocNameEnum.CB.getName().equals(businessType.toString())
                    || (RenovationDocNameEnum.SG.getName().equals(businessType.toString()) && flag != null && "1".equals(flag.toString()))) {
                setCbPageHead(head, writer, document);
            } else if (RenovationDocNameEnum.SG.getName().equals(businessType.toString()) || RenovationDocNameEnum.JC.getName().equals(businessType.toString())) {
                setSinglePageHead(head, writer, document);
            }
        } catch (Exception e) {
            throw new ExceptionConverter(e);
        }
    }

    /**
     * Chunk的offsetX控制页眉图片水平位置,offsetY会影响到图片大小; 图片上下位置可通过showTextAligned的y来控制
     * 页眉下划线通过setTotalWidth控制先长度,writeSelectedRows的xPos控制线的起始水平位置
     *
     * @param head
     * @param writer
     * @param document
     * @throws DocumentException
     */
    private void setSinglePageHead(PdfPTable head, PdfWriter writer, Document document) throws DocumentException {
        Font font = PdfUtil.getFont(null);
        // 通过表格构建页眉下划线
        head.setTotalWidth(PageSize.A4.getWidth() - 105);
        head.setWidths(new int[]{24});
        head.setLockedWidth(true);
        head.getDefaultCell().setFixedHeight(-10);
        head.getDefaultCell().setBorder(Rectangle.BOTTOM);
        head.getDefaultCell().setBorderWidth(0.5f);
        head.addCell(new Paragraph(" ", font));
        // 将页眉写到document中,位置可以指定,指定到下面就是页脚
        head.writeSelectedRows(0, -1, 55, PageSize.A4.getHeight() - 20, writer.getDirectContent());
        PdfContentByte directContent = writer.getDirectContent();
        // 最重要的是这个,如果页眉需要设置图片的话,需要在Phrase对象中添加一个Chunk对象,在Chunk对象中添加图片信息即可
        Phrase phrase = new Phrase("", font);
        Image img = PdfUtil.getImg();
        if (img != null) {
            phrase.add(new Chunk(img, 30, -150));
        }
        // 写入页眉
        ColumnText.showTextAligned(directContent, Element.ALIGN_RIGHT, phrase, document.right(), PageSize.A4.getHeight() + 48, 0);
    }
  • 通过PdfPTable来构建下划线
  • 通过new Chunk来显示图片,并通过ColumnText.showTextAligned来展示在页眉
  • 详细见setSinglePageHead方法的注释,方正就是一顿调,知道合适位置
2. document参数传递:
  • 像下述这样定义一个字符串参数于document,就可以像上述PdfEvent中获取做业务判断
  • 使用的时候注意toString()
PdfName businessType = new PdfName("businessType");
document.setAccessibleAttribute(businessType, new PdfString(type));
3. 生成的pdf文件转base64编码:
  • 主要以下两个方法,FileUtil是hutool的工具类,Base64是java.util的工具类

	PdfUtil.getBase64(FileUtil.readBytes(file));
	
    public static String getBase64(byte[] buffer) {
        return Base64.getEncoder().encodeToString(buffer);
    }
4. 平方²上标显示问题:

本人生成pdf时用的是simkai.ttf字体,输出的pdf没有显示²上标文章来源地址https://www.toymoban.com/news/detail-561913.html

  • 要么可以换字体,百度即可
  • 要么像如下这样,通过setTextRise来控制文字位置,来大概展示成²效果
  • 方法正值为上标,负值可为下标,注意上标的2的文字specialFont字体要定义小点,本人定义5
 public static PdfPCell getPDFCellSpecial(String name, Font font, Integer alignment) {
        PdfPCell cell = new PdfPCell();
        if (name == null) {
            name = " ";
        }
        Paragraph p = new Paragraph(name, font);
        Font specialFont = PdfUtil.getSpecialFont(null);
        Chunk chunk = new Chunk("2", specialFont);
        chunk.setTextRise(5f);
        p.add(chunk);
        p.add(new Chunk(")", font));

        if (alignment == null) {
            p.setAlignment(Element.ALIGN_CENTER);
        } else {
            p.setAlignment(alignment);
        }
        cell.setUseAscender(true);
        cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
        cell.addElement(p);
        return cell;
    }
5. 压缩包的文件流InputStream输出文件:
  • 业务上从别的接口获取到一个zip包的文件流,需要将zip包的文件输出到目录,如下代码:
  • 涉及IO流要注意关流

    private static List<String> extractAllByInputStream(InputStream inputStream, String pdfPath) {
        ArrayList<String> list = Lists.newArrayList();
        try {
            dealZipInputStream(inputStream, pdfPath, list);
        } catch (IOException e) {
            LOGGER.info("下载pdf到本地异常,异常信息:{}", e);
        }

        return list;
    }

    private static void dealZipInputStream(InputStream inputStream, String pdfPath, ArrayList<String> list) throws IOException {
        byte[] buffer = new byte[1024];
        ZipEntry zipEntry;
        try (ZipInputStream zipInputStream = new ZipInputStream(inputStream)) {
            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                String entryName = zipEntry.getName();
                if (!zipEntry.isDirectory()) {
                    String fileName;
                    if (entryName.contains(RenovationDocNameEnum.CB.getName())) {
                        fileName = pdfPath + RenovationDocNameEnum.CB.getName() + ".pdf";
                    } else if (entryName.contains(RenovationDocNameEnum.JC.getName())) {
                        fileName = pdfPath + RenovationDocNameEnum.JC.getName() + ".pdf";
                    } else if (entryName.contains(RenovationDocNameEnum.SG.getName())) {
                        fileName = pdfPath + RenovationDocNameEnum.SG.getName() + ".pdf";
                    } else {
                        fileName = pdfPath + UUID.randomUUID() + ".pdf";
                    }
                    list.add(fileName);
                    File subFile = new File(fileName);
                    subFile.createNewFile();
                    readSubFile(subFile, zipInputStream, buffer);

                }
                zipInputStream.closeEntry();
            }
        } finally {
            IOUtils.closeQuietly(inputStream);
        }
    }

    private static void readSubFile(File subFile, ZipInputStream zipInputStream, byte[] buffer) {
        int len;
        try (FileOutputStream fileOut = new FileOutputStream(subFile)) {
            while ((len = zipInputStream.read(buffer)) > 0) {
                fileOut.write(buffer, 0, len);
            }
        } catch (IOException e) {
            throw new ExceptionConverter(e);
        }
    }

6. itext5进行pdf合并:
  • 本人文件合并后要删除之前的文件,这时需要注意new PdfReader(inputStream)时使用inputStream
  • 不然可能出现:别的程序正在使用而无法删除情况

    /* 合并pdf文件
     * @param files 要合并文件数组(绝对路劲{ "D:\\a.pdf", "D:\\b.pdf" })
     * @param savePath 合并后新产生的文件绝对路径如D:\\temp.pdf
     */
    public static Integer mergePdfFiles(String[] files, String savePath) {
        Document document = null;
        PdfCopy copy = null;
        try (FileOutputStream outputStream = new FileOutputStream(savePath)) {
            // 创建一个与a.pdf相同纸张大小的document
            document = new Document(new PdfReader(files[0]).getPageSize(1));
            copy = new PdfCopy(document, outputStream);
            document.open();
            for (int i = 0; i < files.length; i++) {
                // 一个一个的遍历现有的PDF
                dealFile(files[i], copy, document);
            }
            copy.close();
            document.close();
            return 1;
        } catch (IOException | DocumentException e) {
            LOGGER.info("合并pdf失败,异常信息:{}", e);
        } finally {
            if (document != null) {
                document.close();
            }
            if (copy != null) {
                copy.close();
            }
        }
        return 0;
    }

    private static void dealFile(String file, PdfCopy copy, Document document) {
        PdfReader reader = null;
        try (FileInputStream inputStream = new FileInputStream(file)) {
            reader = new PdfReader(inputStream);
            int n = reader.getNumberOfPages();// PDF文件总共页数
            for (int j = 1; j <= n; j++) {
                document.newPage();
                PdfImportedPage page = copy.getImportedPage(reader, j);
                copy.addPage(page);
            }
            reader.close();
        } catch (IOException | BadPdfFormatException e) {
            throw new ExceptionConverter(e);
        } finally {
            if (reader != null) {
                reader.close();
            }
        }

    }

到了这里,关于itext5创建pdf表格及遇到的一些问题的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在 VScode 终端上创建 nuxtjs 项目遇到的问题以及使用 GitHub 遇到的问题和一些个人笔记

    这篇文章是关于在vscode终端中创建 nuxtjs项目 的一些步骤,同时还包括了使用 Git、GitHub 的一些操作,以此文章作为笔记,仅供参考。(前提:已经安装nodejs、git) 关于nuxtjs、ssr、服务端渲染、nuxtjs项目结构等等相关知识点这篇文章就不多多介绍了,在后续的文章或笔记中也

    2024年02月09日
    浏览(74)
  • 【Java】使用iText生成PDF文件

    iText介绍 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件。 项目要使用iText,必须引入jar包。才能使用,maven依赖如下: 输出中文,还要引入下面itext-asian.jar包:  

    2024年02月10日
    浏览(41)
  • Java 使用 itext 向PDF插入数据和图片

    一、下载Adobe Acrobat DC 二、制作模板 1、准备一个word模板,并转换成PDF格式 2、使用Adobe Acrobat DC打开PDF文档,并在右侧搜索框搜索表单,点击准备表单 3、点击开始,制作PDF表单 4、扫描完成后如下图,蓝白色框就是可编辑表单 5、点击表单编辑表单名称以及插入时的字体大小

    2024年02月09日
    浏览(38)
  • java中使用Jsoup和Itext实现将html转换为PDF

    1.在build.gradle中安装所需依赖: 2.创建工具类,实现转换方法 3.base64过滤类: 4.字体类代码,window用户可在C:windowsfont中寻找自己所需字体即可。我这里用的为黑体: simhei.ttf 效果如下: html页面预览: pdf页面预览:    

    2024年02月14日
    浏览(37)
  • 【Java】OpenPDF、iText、PDFBox 是三种常用的 PDF 处理库

    OpenPDF、iText、PDFBox 是三种常用的 PDF 处理库,它们各自具有独特的优势和特点,同时也存在一些局限性和差异。本文将对这四种库进行详细的比较,并通过代码示例来展示它们的使用。 1、OpenPDF OpenPDF 是一个用于创建和编辑 PDF 文档的 Java 库,它基于 iText 库的一个分支,提供

    2024年02月09日
    浏览(61)
  • 关于Kettle ETL java脚本编写遇到的一些问题记录

    使用方法**logBasic()**参数必须是字符串 这部分内容会在ETL的日志窗口显示 1.获取上个节点传输的数据 可以直接在左侧双击获取 2.全局参数获取 在启动运行的变量设置参数 在java代码中获取方式 3.获取当前节点参数 在当前窗口下方有个 参数 Tab页,在这里设置 在java代码中获取

    2024年02月12日
    浏览(41)
  • Java集成阿里云的实时语音识别遇到的一些问题

    集成阿里云的实时语音识别遇到的问题: 困扰了一周时间,主要涉及到流的处理问题。 集成是通过引用maven依赖加载。 前端录音通过流的方式传到后端,后端再把流上传到Minio,后端拿到文件地址,调微服务(集成语音识别的是另一个独立的微服务)去Minio获取输入流,再上传到

    2024年02月02日
    浏览(35)
  • 使用IText导出复杂pdf

            需要将发票导出成pdf,要求每页都必须包含发票信息和表头行。         使用IText工具实现PDF导出         IText8文档:Examples (itextpdf.com)                  引入Itext依赖,我这里用的是8.0.1版本         测试一下:         IText8不支持中文,需要引入外部

    2024年02月12日
    浏览(36)
  • 使用gradio创建一个提取pdf、excel中表格数据的demo

    在线体验地址 (https://swanhub.co/patch/TabularScan/demo) 大家可以在上面的链接中试用,需求不大也不用自己弄代码了。 后续大家如果有一些代码或功能想快速部署、提供服务,不管是 AI 项目或是 web 项目,也可以直接托管在 swanhub开源社区 上,方便快捷,而且免费 最近需要对pdf、

    2024年02月09日
    浏览(58)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包