itext7相关使用

最近有使用到itext7相关技术,生成pdf文件,添加电子签章等功能.

1 itext7的简介

iText 7是基于iText 5的一款工具. 其中所有主类和接口的完整版本,都更合乎逻辑,尽可能保持与iText 5的兼容, 一个全新的布局模块,它超越了iText 5,优化添加了很多高级布局功能.

itext7中的语法, 其中一些命名等和前端的语法相似. 如其中的div,table等语法糖.

2 itext7的使用

1 添加相关maven坐标

 <!-- itext7 全家桶 -->
    <dependency>
      <groupId>com.itextpdf</groupId>
      <artifactId>itext7-core</artifactId>
      <version>7.1.12</version>
      <type>pom</type>
    </dependency>

    <!--itext7 html转pdf用到的包-->
    <dependency>
        <groupId>com.itextpdf</groupId>
        <artifactId>html2pdf</artifactId>
        <version>3.0.0</version>
    </dependency>

2 itext7相关语法说明

1 PDF生成案例
public class PdfDemo { 
	// 生产的pdf文件路径
    public static final String DEST = "D:\\demo.pdf";
	// 字体
    public static final String FONT = "ttf/方正小篆体.ttf";


	public Document getDocument(){	
        PdfDocument pdfDocument;
        Document document;
        PdfFont font ;
        try{
            pdfDocument = new PdfDocument(new PdfWriter(DEST));
            // 项目指定字体, 通过类加载项目字体资源
            font = font = PdfFontFactory.createFont(
                IOUtils.toByteArray(PdfDemo.class.getClassLoader().getResourceAsStream(FONT)), 
                PdfEncodings.IDENTITY_H, false);;
            document = new Document(pdfDocument)
   			document.setFont(font);
			return document;
        }catch(Exception e){
            e.printStackTrace();
        }
	}
}   

从案例可以, 生成Document对象的步骤.接下来,一步一步看Document对象创建的过程

com.itextpdf.layout.Document类部分源码:

/**
 * Document is the default root element when creating a self-sufficient PDF. It
 * mainly operates high-level operations e.g. setting page size and rotation,
 * adding elements, and writing text at specific coordinates. It has no
 * knowledge of the actual PDF concepts and syntax.
 * <p>
 * A {@link Document}'s rendering behavior can be modified by extending
 * {@link DocumentRenderer} and setting an instance of this newly created with
 * {@link #setRenderer(com.itextpdf.layout.renderer.DocumentRenderer) }.
 */
// Document文档是创建自定义PDF时的默认根元素
// 它主要操作高级操作,例如设置页面大小和旋转,添加元素,并在特定坐标处写入文本
public class Document extends RootElement<Document> {
    
   /**
     * Creates a document from a {@link PdfDocument}. Initializes the first page
     * with the {@link PdfDocument}'s current default {@link PageSize}.
     *
     * @param pdfDoc the in-memory representation of the PDF document
     */
    // 常用构造方法 使用PdfDocument对象
    public Document(PdfDocument pdfDoc) {
        this(pdfDoc, pdfDoc.getDefaultPageSize());
    }
    
    @Override
    public Document add(IBlockElement element) {
        checkClosingStatus();
        super.add(element);
        if (element instanceof ILargeElement) {
            ((ILargeElement) element).setDocument(this);
            ((ILargeElement) element).flushContent();
        }
        return this;
    }
    
    /**
     * Sets the font of this Element.
     * <p>
     * This property overrides the value set by {@link #setFontFamily}. Font is set either via exact {@link PdfFont}
     * instance or via font-family name that should correspond to the font in {@link FontProvider}, but not both.
     * @param font a {@link PdfFont font}
     * @return this Element.
     */
    // 设置元素的字体
    public T setFont(PdfFont font) {
        setProperty(Property.FONT, font);
        return (T) (Object) this;
    }
    
}

com.itextpdf.kernel.pdf.PdfDocument类部分源码:

/**
 * Main enter point to work with PDF document.
 */
// 使用PDF文档的主输入点
public class PdfDocument implements IEventDispatcher, Closeable, Serializable {
    
   /**
     * Open PDF document in writing mode.
     * Document has no pages when initialized.
     *
     * @param writer PDF writer
     */
    // 以编写模式打开PDF文档 ,文档初始化时没有页面 
    public PdfDocument(PdfWriter writer) {
        this(writer, new DocumentProperties());
    }
    
}

com.itextpdf.kernel.pdf.PdfWriter类部分源码:

    /**
     * Create a PdfWriter writing to the passed filename and with default writer properties.
     *
     * @param filename filename of the resulting pdf.
     * @throws FileNotFoundException
     */
	// 创建一个PdfWriter,将其写入传递的文件名并具有默认的writer属性
    public PdfWriter(String filename) throws FileNotFoundException {
        this(filename, new WriterProperties());
    }
2 图片相关语法

其中主要是创建com.itextpdf.io.image.ImageData对象来获取图片源,通过其工厂类com.itextpdf.io.image.ImageDataFactory来创建对象.


  // 得到需要插入的图片   常使用两种方式获取: 即 url 和 filename
  ImageData imageData = ImageDataFactory.create("C:\\Pdf图片.png");
  // 得到填充PDF的Image对象, 可以设置图片的各种参数
  Image image = new Image(imageData)
  // 设置宽高扩大缩小
  image.scale(1, 1.05f);
  // 将图像缩放到绝对大小
  image.scaleAbsolute(80, 80);
  // 设置边距
  image.setMargins(-50, -60, -60, -60);

ImageDataFactory工厂类部分源码:

    /**
     * Create an ImageData instance representing the image from the file located at the specified url.
     * @param url location of the image
     * @return The created ImageData object.
     */
    public static ImageData create(URL url) {
        return create(url, false);
    }

    /**
     * Create an ImageData instance representing the image from the specified file.
     * @param filename filename of the file containing the image
     * @param recoverImage whether to recover from a image error (for TIFF-images)
     * @return The created ImageData object.
     * @throws MalformedURLException
     */
    public static ImageData create(String filename, boolean recoverImage) throws MalformedURLException {
        return create(UrlUtil.toURL(filename), recoverImage);
    }

    /**
     * Create an ImageData instance representing the image from the specified file.
     * @param filename filename of the file containing the image
     * @return The created ImageData object.
     * @throws MalformedURLException
     */
    public static ImageData create(String filename) throws MalformedURLException {
        return create(filename, false);
    }

Image类部分源码:

    /**
     * Creates an {@link Image} from an image resource, read in from a file
     * with the iText I/O module.
     *
     * @param img an internal representation of the {@link com.itextpdf.io.image.ImageData image resource}
     */
    public Image(ImageData img) {
        this(new PdfImageXObject(checkImageType(img)));
        setProperty(Property.FLUSH_ON_DRAW, true);
    }

    /**
     * Scale the image to an absolute size. This method will <em>not</em>
     * preserve the width-height ratio of the image.
     *
     * @param fitWidth  the new absolute width of the image
     * @param fitHeight the new absolute height of the image
     * @return this element
     */
    public Image scaleAbsolute(float fitWidth, float fitHeight) {
        float horizontalScaling = fitWidth / xObject.getWidth();
        float verticalScaling = fitHeight / xObject.getHeight();
        return scale(horizontalScaling, verticalScaling);
    }

    /**
     * Sets the margins around the image to a series of new widths.
     *
     * @param marginTop    the new margin top width
     * @param marginRight  the new margin right width
     * @param marginBottom the new margin bottom width
     * @param marginLeft   the new margin left width
     * @return this image
     */
    public Image setMargins(float marginTop, float marginRight, float marginBottom, float marginLeft) {
        return setMarginTop(marginTop).setMarginRight(marginRight).setMarginBottom(marginBottom).setMarginLeft(marginLeft);
    }

    /**
     * Scale the image relative to its default size.
     *
     * @param horizontalScaling the horizontal scaling coefficient. default value 1 = 100%
     * @param verticalScaling   the vertical scaling coefficient. default value 1 = 100%
     * @return this element
     */
    public Image scale(float horizontalScaling, float verticalScaling) {
        setProperty(Property.HORIZONTAL_SCALING, horizontalScaling);
        setProperty(Property.VERTICAL_SCALING, verticalScaling);
        return this;
    }
3 添加空白页

添加第2页为空白页,立即刷新后再继续添加

pdfDocument.addNewPage(2).flush();
4 Div和Paragraph

   			// 块状
   			Div div = new Div();
            // 设置宽度
            div.setWidth(UnitValue.createPercentValue(100));
            // 设置高度
            div.setHeight(UnitValue.createPercentValue(100));
            // 设置此元素的水平对齐方式
            div.setHorizontalAlignment(HorizontalAlignment.CENTER);

  			// 添加段落
 			Paragraph paragraph = new Paragraph("PDF内容");
            // 设置此元素的水平对齐方式
            paragraph.setHorizontalAlignment(HorizontalAlignment.CENTER);
            // 设置此元素的最宽长度
            paragraph.setMaxWidth(UnitValue.createPercentValue(75));
            // 设置元素的上边距宽度
            paragraph.setMarginTop(180f);
            // 定义文本元素的所有字符之间的自定义间距
            paragraph.setCharacterSpacing(0.4f);
            // 设置对齐方式
            paragraph.setTextAlignment(TextAlignment.CENTER);
            // 设置段落前留多少空
            paragraph.setFirstLineIndent(24);

			// 表格
            Table table = new Table(8);
            table.addHeaderCell("添加头部单元格");
            table.addCell("普通单元格");
            // 设置单元格对齐方式
            table.addCell(new Cell().setTextAlignment(TextAlignment.CENTER));
            // 宽度和页面一致
            table.useAllAvailableWidth();
            // 新起一行
            table.startNewRow();

			// 添加到文档
            document.add(new Div().add(table));

 			document.add(div);
  			document.add(paragraph);

从Document的add方法可知, 此处添加的IBlockElement对象.

IBlockElement源码:

public interface IBlockElement extends IElement {
}

IBlockElement接口的唯一抽象子类BlockElement 而BlockElement的子类包括:

  • Cell 单元格元素,常在Table中使用

  • Div 块状元素, 作为一个整体,如可添加一个Table表格放进去,这个表格就是一个整体,表格数据量很大,涉及到分页,会自动向后下一页分页.

    • ListItem 列表项
  • LineSeparator 行分隔符

  • List 列表

  • Paragraph 段落,普通的一段文字

  • Table 表格

5 换行/空格/换页
  • 换行使用\n
  • tab效果使用\u00a0符号, 一般连着使用8个.
  • 使用Tab和TabStop类来控制缩进
     // 空格
	 paragraph.add(new Text("\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0第一行缩进"));    
	 paragraph.add(new Tab());
     paragraph.addTabStops(new TabStop(20, TabAlignment.LEFT));

 	 // 换页
	 document.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
6 Html转换为Pdf
            ConverterProperties proper = new ConverterProperties();
            //字体设置,解决中文不显示问题
            FontSet fontSet = new FontSet();
			// 加载自定义字体
            fontSet.addFont(PdfDemo.class.getClassLoader().getResource("ttf/SourceHanSansCN-Regular.ttf").getPath(), PdfEncodings.IDENTITY_H);
            FontProvider fontProvider = new FontProvider(fontSet);
            proper.setFontProvider(fontProvider);

            String content = "html内容";
			// 使用jar包提供的方法转换成IElement对象, 而IElement对象正是所有填充对象的最上层接口, 可以转换为 Div ,Paragraph对象填充到PDF
            List<IElement> elements = HtmlConverter.convertToElements(content, proper);
			// 定义填充PDF块
            Div div = new Div();
			// 遍历元素,封装数据
            for (IElement iElement : elements) {
                if (iElement instanceof Div) {
                    div.add((Div) iElement);
                } else if (iElement instanceof Paragraph) {
                    div.add((Paragraph) iElement);
                }
            }
            document.add(div);
7 关于PDF上签章功能

方法一

通过保存签章图片,把图片生成Image对象,设置好对应的坐标位置,添加到document中.

方法二

通过生成电子签章,直接将Pdf文件转化成字节流,添加签章的关键字,位置坐标大小等属性,签章服务器将生成后的PDF转换成字节流传回,本地获取成为PDF文件保存即可.

参考资料:

https://blog.csdn.net/tzxylao/article/details/106486009

https://kb.itextpdf.com/home/it7kb/ebooks/itext-7-building-blocks

https://blog.csdn.net/lxwfly/article/details/106895695

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于使用 iText7 进行签名和验签,可以使用 IExternalSignatureContainer 接口进行操作。该接口可以用于实现自定义的数字签名算法。 具体操作步骤如下: 1. 实现 IExternalSignatureContainer 接口,该接口包含两个方法: ``` public byte[] sign(InputStream data); public void modifySigningDictionary(PdfDictionary signDic); ``` 2. 在实现类中实现 sign 方法,该方法用于计算签名值。在该方法中,可以使用自定义的数字签名算法进行签名操作。 3. 在实现类中实现 modifySigningDictionary 方法,该方法用于修改签名字典中的值。在该方法中,可以设置签名算法、证书等相关信息。 4. 调用 PdfSigner 类中的 signDetached 方法进行签名,该方法接受三个参数: ``` public void signDetached(IExternalSignatureContainer externalSignatureContainer, IExternalDigest externalDigest, byte[] documentBytes, Collection<CrlClient> crlList, OcspClient ocspClient, TSAClient tsaClient, int estimatedSize, MakeSignature.CryptoStandard sigtype, PdfName fieldname, PdfSignatureAppearance appearance, Collection<ICrlClient> crlClients) ``` 其中,externalSignatureContainer 参数为实现了 IExternalSignatureContainer 接口的类的实例,externalDigest 参数为实现了 IExternalDigest 接口的类的实例,documentBytes 参数为 PDF 文件的二进制数据。 5. 调用 PdfSigner 类中的 verifySignature 方法进行验签,该方法接受一个参数: ``` public void verifySignature(IExternalSignatureVerifier externalSigVerifier) ``` 其中,externalSigVerifier 参数为实现了 IExternalSignatureVerifier 接口的类的实例,该类用于验证签名。 以上就是使用 iText7 进行签名和验签的基本步骤。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值