itext5 PdfStamper渲染 设置BaseFont字体,但是生成pdf文件过大

遇到的问题

1.addSubstitutionFont  设置字体填充不生效,以及生成的pdf文件过大

解决:删除itext-asian 包引用

2.BaseFont无法设置粗体

解决:用getFieldPositions 加载文本框 通过Font类来设置粗体.

3.文本框设置粗体大号文字产生位移

解决:自己调整new Paragraph 的几个参数控制.

pom必须引入
 


        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.4.3</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf.tool</groupId>
            <artifactId>xmlworker</artifactId>
            <version>5.4.1</version>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.0</version>
        </dependency>

通用生成示例

package com.example.pdftmpelet;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;

import java.io.*;
import java.util.List;

/**
 * 使用pdf模板生成pdf文件
 */
public class WriteToPDF {

    public static String create(String mobanPath,String fileName,String textFields,String imgFields) {
        JSONArray text=JSONArray.parseArray(textFields);
        JSONArray img=JSONArray.parseArray(imgFields);
            
        File f=new File("D:\\"+fileName+System.currentTimeMillis()+".pdf");

        OutputStream os = null;
        PdfStamper ps = null;
        PdfReader reader = null;
        try {
            // 1 获取文件的输出流
            os = new FileOutputStream(f);
            // 2 读取pdf模板
            reader = new PdfReader(mobanPath);
            // 3 根据表单生成一个新的pdf
            ps = new PdfStamper(reader, os);
            // 4 获取pdf表单
            AcroFields form = ps.getAcroFields();
            ps.setFormFlattening(true);


            // 拼接字体文件的完整路径

            // 5 给表单添加中文字体
            BaseFont font = BaseFont.createFont("C:/Windows/Fonts/simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            font.setSubset(true);
            form.addSubstitutionFont(font);

            // 6遍历data赋值到form
            if(text!=null && text.size()>0){
                for (int i = 0; i < text.size(); i++) {
                    JSONObject o = text.getJSONObject(i);
                    String key=o.getString("KEY");
                    String value=o.getString("VALUE");
                    String fontsize=o.getString("SIZE");
                    String ifBlod=o.getString("BLOD");
                    Float sze=12f;
                    try {
                        sze=fontsize==null?sze:Float.parseFloat(fontsize);
                    }catch (Exception e){
                        System.out.println("font size error!"+fontsize);
                    }
                    //如果是加粗就使用 Rectangle 写入, 这里有个坑, 字号过大会跑出去. 可以自己调整new Rectangle 的几个值来兼容.
                    if("Y".equals(ifBlod)){
                        int tpdd=sze.intValue()-12-2;
                        Font blod = new Font(font, sze, Font.BOLD);
                        List<AcroFields.FieldPosition> multiLinePosition = form.getFieldPositions(key);
                        int page = multiLinePosition.get(0).page;
                        Rectangle rectangle = multiLinePosition.get(0).position;
                        float left = rectangle.getLeft();
                        float right = rectangle.getRight();
                        float top = rectangle.getTop();
                        float bottom = rectangle.getBottom();
                        PdfContentByte pdfContentByte = ps.getOverContent(page);
                        ColumnText columnText = new ColumnText(pdfContentByte);
                        Rectangle r = new Rectangle(left, bottom, right, top-(tpdd>0?tpdd:0));
                        columnText.setSimpleColumn(r);
                        Chunk chunk = new Chunk(value);

                        Paragraph paragraph = new Paragraph(12, chunk);
                        columnText.addText(paragraph);
                        paragraph.setFont(blod);
                        columnText.addElement(paragraph);
                        columnText.go();
                    }else{
                        form.setFieldProperty(key, "textsize", sze, null);
                        form.setFieldProperty(key, "spacing", 1f, null);
                        form.setField(key, value);
                    }

                }

            }

            
            // 7 填充图片到form
            PdfStamper stamper = ps;

            if(img!=null && img.size()>0){
                for (int i = 0; i < img.size(); i++) {
                    JSONObject o = img.getJSONObject(i);
                    String key=o.getString("KEY");
                    String value=o.getString("VALUE");

                    try {
                        List<AcroFields.FieldPosition> fieldPositions = form.getFieldPositions(key);
                        for (AcroFields.FieldPosition fieldPosition : fieldPositions) {
                            // 通过域名获取所在页和坐标,左下角为起点
                            int pageno = fieldPosition.page;
                            Rectangle signrect = fieldPosition.position;
                            float x = signrect.getLeft();
                            float width = signrect.getWidth();
                            float y = signrect.getBottom();
                            // 读图片
                            Image image = Image.getInstance(value);
                            float img_width = image.getWidth();
                            // 获取操作的页面
                            PdfContentByte under = stamper.getOverContent(pageno);
                            // 图片的大小
                            image.scaleToFit(signrect.getWidth(), signrect.getHeight());
                            // 添加图片
                            image.setAbsolutePosition(x, y);
                            under.addImage(image);
                        }
                    } catch (BadElementException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    } catch (DocumentException e) {
                        e.printStackTrace();
                    }

                }

            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                ps.close();
                reader.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
 


        return f.getAbsolutePath();
    }




    public static void main(String[] args) {
        String text="[{\"KEY\":\"文本域名称\",\"VALUE\":\"填充值\",\"SIZE\":\"20\",\"BLOD\":\"Y\"},{\"KEY\":\"文本域名称\",\"VALUE\":\"123123\"},{\"KEY\":\"文本域名称\",\"VALUE\":\"123123\",\"BLOD\":\"Y\"},{\"KEY\":\"文本域名称\",\"VALUE\":\"123456\"}]";
        String img="[{\"KEY\":\"图片渲染\",\"VALUE\":\"本地图片绝对路径或者网络图片url\"}]";
        //生成pdf文件 通过json指定一堆待填充 的文本域名称, 值, 字号, 是否加粗 
        String rsp=create("D:\\moban.pdf","测试1",text,img);
        System.out.println(rsp);
    }



}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
iText是一个用于生成PDF文件Java库,而iText 5.5.6是其一个版本。在iText 5.5.6中,可以通过设置字体来自定义PDF文件字体样式。 首先,你需要导入所需的字体文件iText支持TrueType字体(.ttf)和OpenType字体(.otf)。你可以从官方网站或其他来源下载所需的字体文件。 接下来,你可以使用BaseFont类来创建字体对象。BaseFont类提供了多种方法来加载字体文件,并可以设置字体的样式、大小等属性。例如,你可以使用以下代码创建一个Arial字体对象: ``` BaseFont baseFont = BaseFont.createFont("path/to/arial.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED); Font font = new Font(baseFont, 12, Font.NORMAL); ``` 在上述代码中,"path/to/arial.ttf"是你下载的Arial字体文件的路径。BaseFont.IDENTITY_H表示使用Unicode编码,BaseFont.EMBEDDED表示将字体文件嵌入到生成PDF文件中。Font.NORMAL表示正常的字体样式,你还可以根据需要设置其他样式,如粗体、斜体等。 接下来,你可以使用创建的字体对象来设置文本的字体样式。例如,你可以使用以下代码将文本添加到PDF文件中,并设置为Arial字体: ``` Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("path/to/output.pdf")); document.open(); Paragraph paragraph = new Paragraph("Hello, World!", font); document.add(paragraph); document.close(); writer.close(); ``` 在上述代码中,我们创建了一个Paragraph对象,并将字体对象作为参数传递给它。然后,我们将该段落添加到PDF文件中。 这样,你就可以使用iText 5.5.6来生成PDF文件设置字体样式了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值