OpenPDF的学习文档(第十章·PDF阅读)

PDF阅读器

  • PdfReader(String filename) filename = PDF绝对路径。

  • PdfReader(String filename, byte[] ownerPassword) ownerPassword = 打开PDF需要的密码。

  • PdfReader(InputStream is) is = PDF的输入流

  • PdfReader(InputStream is, byte[] ownerPassword)

  • PdfReader(byte[] pdfIn) pdfIn = PDF的字节数组。

  • PdfReader(byte[] pdfIn, byte[] ownerPassword)

  • PdfReader(URL url)url = PDF的地址。

  • PdfReader(URL url, byte[] ownerPassword)

  • PdfReader(RandomAccessFileOrArray raf, byte[] ownerPassword) 一般用在巨大型PDF的读取,或者只读取PDF的某页,才使用。

  • PdfReader(String filename, Certificate certificate, Key certificateKey, String certificateKeyProvider) 打开公钥/PKI 证书加密的PDF。

  • PdfReader(PdfReader reader) 创建一个副本。

  • @Test
    public void readPDF() throws IOException {
        PdfReader reader = new PdfReader("C:/TMP/PXC11ManLiteSm.pdf");
        log.info("文档总页数:{}", reader.getNumberOfPages());
        log.info("文档版本:{}", reader.getPdfVersion());
        log.info("文档长度:{}", reader.getFileLength());
        log.info("文档元数据:{}", reader.getInfo());
        // log.info("文档XML元数据:{}", reader.getMetadata());
        log.info("文档是否加密:{}", reader.isEncrypted());
        log.info("文档持有权限:{}", reader.getPermissions());
        log.info("文档加密类型/算法:{}", reader.getCryptoMode());
    
        // 文本提取器
        PdfTextExtractor extractor = new PdfTextExtractor(reader);
        // 获取总页数
        int pages = reader.getNumberOfPages();
    
        for (int i = 0; i < pages; i++) {
            String values = extractor.getTextFromPage(i + 1);
            Rectangle pageSize = reader.getPageSize(i + 1);
            // Rectangle cropBox = reader.getCropBox(i);
            int pageRotation = reader.getPageRotation(i + 1);
            PdfDictionary pageN = reader.getPageN(i + 1);
            log.info("第{}页提取到文本:{}", i + 1, values);
            log.info("第{}页提页面大小:{}", i + 1, pageSize);
            log.info("第{}页提页面旋转角度:{}", i + 1, pageRotation);
            log.info("第{}页提页面词典:{}", i + 1, pageN);
        }
    
        // 读取表单
        // 读取签名
        AcroFields acroFields = reader.getAcroFields();
        // 获取所有表单数据
        Map<String, AcroFields.Item> allFields = acroFields.getAllFields();
        for (String name : allFields.keySet()) {
            String fieldValue = acroFields.getField(name);
            int fieldType = acroFields.getFieldType(name);
            log.info("表单名称:{}, 表单类型:{}, 表单值:{}", name, fieldType, fieldValue);
        }
        // 读取附件
        PdfDictionary catalog = reader.getCatalog();
    
        reader.close();
    }
    

表单类型

  • AcroFields的类型
  • FIELD_TYPE_NONE = 0 未知类型
  • FIELD_TYPE_PUSHBUTTON = 1 提交按钮 “提交表单”、“重置表单”、“打印文档”或“跳转页面”
  • FIELD_TYPE_CHECKBOX = 2 复选框
  • FIELD_TYPE_RADIOBUTTON = 3 单选按钮
  • FIELD_TYPE_TEXT = 4 文本框
  • FIELD_TYPE_LIST = 5 列表框,单选或者多选
  • FIELD_TYPE_COMBO = 6 组合框 / 下拉列表
  • FIELD_TYPE_SIGNATURE = 7 签名框

制作表单

  • 这一部分内容建议使用专业的PDF编辑器制作使用,单独使用OpenPDF会很麻烦。
  • TextField 文本框表单域
    • TextField textField = new TextField(writer, new Rectangle(100, 300, 100 + 100, 300 + 50), "textField");
      PdfFormField field = textField.getTextField();
      textField.setBackgroundColor(Color.RED);
      textField.setBorderColor(Color.BLUE);
      textField.setBorderWidth(2);
      textField.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
      textField.setAlignment(Element.ALIGN_CENTER);
      textField.setOptions(TextField.MULTILINE | TextField.REQUIRED);
      textField.setRotation(90);
      writer.addAnnotation(field);
      
  • 剩下的域依此类推。
  • 使用PDF编辑器创建表单
  • image
  • 添加文本框
    *image
    • 注意右侧的属性,着重设置:字段名称,位置,字体,字体大小,字数限制和多行
  • 剩下的依此类推。

准备表单

  • 在PDF编辑器中添加以下元素。
  • image
    • text 为文本框

      • image
      • 注意设置:多行、滚动、字数限制、字体
      • 严重警告: 这里的字体设置完毕后,在OpenPDF的代码中,也要使用这个字体。否则会渲染不成功。
        • 在openPDF中,虽然支持ttf和ttc字体文件,但是对于变体Variable Fonts的ttf支持的不好,只能使用第一个变体。
        • 所以建议注册ttf时,只注册不带变体字体文件。
        • 首先将字体注册进系统中。
        • 在PDF编辑器和OpenPDF选择同一个字体。
    • gender 为单选框

      • 同一组的单选框的name相同,value不同。
      • image
      • 针对单选框可以设置样式。
      • image
    • chang、tiao、rap、lanqiu 为复选框

      • 同一组的单选框的name不同,value可以相同。
      • 比如他们4个的值都可以设置为:Yes
      • image
      • 也可以设置样式
      • image
    • PdfReader reader = new PdfReader("C:/TMP/core.pdf");
      ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
      PdfStamper stamper = new PdfStamper(reader, outputStream);
      
      AcroFields form = stamper.getAcroFields();
      // form.addSubstitutionFont(FontUtils.NOTO_FONT);
      Map<String, String> fieldValues = new HashMap<>();
      fieldValues.put("chang", "Yes");
      fieldValues.put("text", "我是文本框");
      fieldValues.put("tiao", "Yes");
      fieldValues.put("rap", "Yes");
      fieldValues.put("lanqiu", "Yes");
      fieldValues.put("gender", "A");
      
      form.setFieldProperty("text", "textfont", FontUtils.NOTO_FONT,null);
      form.setField("text", "我是文本框");
      for (Map.Entry<String, String> entry : fieldValues.entrySet()) {
          String fieldName = entry.getKey();
          String fieldValue = entry.getValue();
          form.setField(fieldName, fieldValue);
      }
      stamper.setFormFlattening(true);
      stamper.close();
      reader.close();
      Files.write(Paths.get("C:/TMP/core_ok.pdf"), outputStream.toByteArray());
      log.info("PDF创建成功!");
      
    • image

posted @ 2026-07-31 12:17  铁锅炖大鹅ing  阅读(9)  评论(0)    收藏  举报