java.pdf_java提取pdf文件中某一页

java.pdf_java提取pdf文件中某一页这里包含工作中涉及到的与PDF操作有关的方法

java.pdf_java提取pdf文件中某一页"

更新时间:2021-11-29
@[PDF]工具类涉及:1.添加水印 2.设置签名域 3.获取文件签名域信息

这里的方法基于com.itextpdf.text包
maven坐标:

<dependency>
      <groupId>com.itextpdf</groupId>
      <artifactId>itextpdf</artifactId>
      <version>5.5.13.2</version> 
 </dependency>

1.添加水印

 /** * * @param filePath 需要添加水印的文件 * @param waterMark 水印内容 * @param outPath 输出文件路径 * @throws Exception */
  public static void waterMarkAdd(String filePath,String waterMark,String outPath) throws Exception{ 
   
    byte[] bytes = getByteString(filePath);
    PdfReader reader = new PdfReader(bytes);
    PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(outPath));
    BaseFont baseFont = BaseFont.createFont();
    Rectangle pageRect = null;
    PdfGState pdfGState = new PdfGState();
    pdfGState.setFillOpacity(0.3f);
    pdfGState.setStrokeOpacity(0.4f);
    int total = reader.getNumberOfPages()+1;
    JLabel label = new JLabel();
    FontMetrics fontMetrics;
    int textHeight = 0;
    int textWidth = 0;
    label.setText(waterMark);
    fontMetrics = label.getFontMetrics(label.getFont());
    textHeight = fontMetrics.getHeight();
    textWidth = fontMetrics.stringWidth(label.getText());
    PdfContentByte contentByte;
    int numJ = 0 ;
    int numK = 0 ;
    for(int i=1; i<total;i++){ 
   
      pageRect = reader.getPageSizeWithRotation(i);
      contentByte = stamper.getOverContent(i);
      contentByte.saveState();
      contentByte.setGState(pdfGState);
      contentByte.beginText();
      contentByte.setFontAndSize(baseFont,24);
      contentByte.setColorFill(BaseColor.BLACK);
      // 你可以随心所欲的改你自己想要的角度
				for (int height = textHeight; height < pageRect
						.getHeight(); height = height + textHeight * 5) { 
   
					numJ ++ ;
					for (int width =  textWidth; width < pageRect
							.getWidth() + textWidth; width = width + textWidth * 3) { 
   
						numK ++ ;
            // 设置水印文字成角度倾斜
						contentByte.showTextAligned(Element.ALIGN_LEFT,
								waterMark, width - textWidth, height - textWidth,
								35);

					}
				}

// contentByte.showTextAligned(Element.ALIGN_LEFT,
// waterMark, reader.getPageSize(i).getWidth()/2, reader.getPageSize(i).getHeight()/2,
// 45);

      // 添加水印文字
      contentByte.endText();
    }
    stamper.close();
    reader.close();
  }

/** * 文件转byte流 * @param path 文件路径 * @return 返回byte[] * @throws IOException */
  private static byte[] getByteString(String path) throws IOException { 
   
    File file = new File(path);
    byte[] buf = new byte[1024];
    int len = 0;
    FileInputStream fis = new FileInputStream(file);
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    while((len = fis.read(buf))!=-1){ 
   
      bos.write(buf,0,len);
    }
    bos.flush();
    fis.close();
    bos.close();
    return bos.toByteArray();
  }

2.设置签名域

  public static byte[] setSignArea(byte[] tail,Map position, List posConfigSet) throws Exception { 
   
    int xIndex = 0;
    int yIndex = 0;
    int yMax = 780;
    int yMin = 72;
    PdfReader reader = new PdfReader(tail);
    ByteArrayOutputStream baoPdfStream = new ByteArrayOutputStream();
    PdfStamper stamper = new PdfStamper(reader, baoPdfStream);
    // 创建数组签名域
    int width = 50, height = 50;
    int pageNo = position.getInt("PAGE_NUM");
    float x_pos = Float.parseFloat(position.getString("X_POS"))-xIndex;
    float y_pos = Float.parseFloat(position.getString("Y_POS"))-yIndex;
    y_pos = y_pos > yMax ? yMax : y_pos;
    y_pos = y_pos < yMin ? yMin : y_pos;
    Rectangle areaSignatureRect =
        new Rectangle(x_pos,y_pos,x_pos + width,y_pos + height);
    PdfFormField pdfFormField = PdfFormField.createSignature(stamper.getWriter());
    pdfFormField.setWidget(areaSignatureRect, PdfAnnotation.HIGHLIGHT_NONE);
    pdfFormField.setFieldName("signatureOne"); // 签名域标识
    pdfFormField.setPage(pageNo);
    stamper.addAnnotation(pdfFormField, pageNo);
    //必须关闭,否则创建的PDF为0KB
    stamper.close();
    return baoPdfStream.toByteArray();
  }

3.查看签名域信息

需要 com.spire.pdf 包

/** * * @param filePath 文件路径 * @return list 返回签名域信息集 */
  public List<Map<String,String>> getSignature(String filePath) { 
   
    List<Map<String,String>> list = new ArrayList<>();
    Map<String,String> result = new HashMap<>();
    //创建PdfDocument实例
    PdfDocument pdf = new PdfDocument();
    //加载含有签名的PDF文件
    pdf.loadFromFile(filePath);
    //获取域集合
    PdfFormWidget pdfFormWidget = (PdfFormWidget) pdf.getForm();
    PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.getFieldsWidget();
    //遍历域
    for (int i = 0; i < pdfFormFieldWidgetCollection.getCount(); i++) { 
   
    //判定是否为签名域
      if (pdfFormFieldWidgetCollection.get(i) instanceof PdfSignatureFieldWidget) { 
   
      //获取签名域
        PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget) pdfFormFieldWidgetCollection
            .get(i);
        //获取签名
        PdfSignature signature = signatureFieldWidget.getSignature();
        String location = signature.getLocationInfo();
        String reason = signature.getReason();
        String data = signature.getDate().toString();
        String name = signature.getSignatureName();
        result.put("location",location);
        result.put("reason",reason);
        result.put("data",data);
        result.put("name",name);
        list.add(result);
        System.out.println(
            "location:" + location + ",reason:" + reason + ",data:" + data + ",name:" + name);
      }
    }
    return list;
  }

4 获取关键字位置坐标

//因匿名内部类原因定义为成员变量
  private int i = 0;
  /** * 获取关键字位置坐标 * @param pdfIn pdf文件byte流 * @param keyWord 关键字 * @return 位置信息列表 [0]:x [1]:y [2]页数 * @throws Exception */
  public List getPosition(byte[] pdfIn, String keyWord) throws Exception { 
   
    List list = new ArrayList();
    PdfReader pdfReader = new PdfReader(pdfIn);
    int numberOfPages = pdfReader.getNumberOfPages();
    PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
    for (i = 1; i <= numberOfPages; i++) { 
   
      pdfReaderContentParser.processContent(i, new RenderListener() { 
   
        @Override
        public void renderText(TextRenderInfo textRenderInfo) { 
   
          String text = textRenderInfo.getText(); // 整页内容
          if (null != text && text.contains(keyWord)) { 
   
            Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
            float[] arr = new float[3];
            arr[0] = boundingRectange.x;
            arr[1] = boundingRectange.y;
            arr[2] = i;
            list.add(arr);
          }
        }
        @Override
        public void renderImage(ImageRenderInfo arg0) { 
   
        }
        @Override
        public void endTextBlock() { 
   
        }
        @Override
        public void beginTextBlock() { 
   
        }
      });
    }
    return list;
  }

5 签章签名填充日期换页时位置调整

/** * * @param pageSet 文件byte流 * @param position 页数 x y * @return * @throws IOException * @throws DocumentException */
public static byte[] fillDate(byte[] pageSet,List<Float> position) throws IOException, DocumentException { 
   
  //盖章日期填充偏移量 签名与日期同页偏移
  float y = -40f;
  float x = 0f;
  //判断是否翻页标志位
  float index = 73;
  File modelFile = new File(System.getProperty("user.dir"));
  if (!modelFile.exists()) { 
   
    modelFile.mkdirs();
  }
  String nowDate = LocalDate.now().toString();
  PdfReader reader = new PdfReader(pageSet);
  FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + "/" + nowDate + ".pdf");
  PdfStamper stamper = new PdfStamper(reader,fos);
  Integer pageNum = Integer.parseInt(position.get(2).toString());
  String xPos = position.get(0).toString();
  String yPos = position.get(1).toString();
  //签名与日期分页时特殊处理 ,如间距更大需继续特殊处理
  if (java.lang.Float.parseFloat(yPos) < index) { 
   
    pageNum++;
    // 第一行:68 (729)第二行56 (711)第三行44(723)
    if(java.lang.Float.parseFloat(yPos)<74&& java.lang.Float.parseFloat(yPos)>60){ 
   
      y = 729;
    }else if(java.lang.Float.parseFloat(yPos)<60&& java.lang.Float.parseFloat(yPos)>52){ 
   
      y= 711;
    }else if (java.lang.Float.parseFloat(yPos)<48&& java.lang.Float.parseFloat(yPos)>40){ 
   
      y = 723;
    }
  }
  PdfContentByte pdfContentByte = stamper.getOverContent(pageNum);
  pdfContentByte.beginText();
  // 设置字体及字号
  pdfContentByte.setColorFill(BaseColor.DARK_GRAY);
  pdfContentByte.setFontAndSize(BaseFont.createFont(), 10);
  pdfContentByte.showTextAligned(Element.ALIGN_LEFT, nowDate,
      java.lang.Float.parseFloat(xPos) + x, y+ java.lang.Float.parseFloat(yPos), 0);
  pdfContentByte.endText();
  stamper.close();
  // 将输出流关闭
  fos.close();
  reader.close();
  File file = new File(System.getProperty("user.dir") + "/" + nowDate+ ".pdf");
  byte[] outputStream = FileCopyUtils.copyToByteArray(file);
  delFile(file);
  return outputStream;
}

public static void delFile(File file) { 
   
  if (file.exists() && file.isFile()) { 
   
    file.delete();
  }
}

6.PDF模板数据填充

pom依赖

   <dependency>
      <groupId>freemarker</groupId>
      <artifactId>freemarker</artifactId>
      <version>2.3.9</version>
    </dependency>
/** * * @param param 填充参数 * @param bytes 待文件文件流 * @param fileName 文件名 * @return * @throws Exception */
public static String processHtmlParam(Map param,byte[] bytes,String fileName) throws Exception { 
   

    File modelFile = new File(System.getProperty("user.dir"));
    if (!modelFile.exists()) { 
   
      modelFile.mkdirs();
    }

    FileOutputStream fos = null;
    try { 
   
      fos = new FileOutputStream(System.getProperty("user.dir") + "/" + fileName);
      fos.write(bytes);
    }catch (Exception e) { 
   
      System.out.println("文件写入失败 : " + e.getMessage());
    } finally { 
   
      if ( null!=fos ) { 
   
        fos.close();
      }
    }
    Configuration config = new Configuration();
    config .setDirectoryForTemplateLoading(modelFile);
    config .setObjectWrapper(new DefaultObjectWrapper());
    config .setDefaultEncoding("UTF-8");
    config .setClassicCompatible(true);

    Template template = config .getTemplate(fileName);

    StringWriter stringWriter = new StringWriter();
    BufferedWriter writer = new BufferedWriter(stringWriter);
    template.process(param, writer);
    String htmlStr = stringWriter.toString();

    writer.flush();
    writer.close();

    delFile(System.getProperty("user.dir"),fileName);

    return htmlStr;
  }

7.将字符串转换为PDF

 /** * 根据html字符串内容生成pdf * * @param pdfFilePath pdf文件存储位置 * @param htmlcontent html内容 */
  public static void parseHtml2PdfByString(String pdfFilePath, String htmlcontent) throws Exception{ 
   
    Document document = new Document();
    PdfWriter writer = null;
    try { 
   
      writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
      // 设置底部距离60,解决重叠问题
      document.setPageSize(PageSize.A4);
      document.setMargins(50, 45, 50, 60);
      document.setMarginMirroring(false);
      document.open();
      XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmlcontent.getBytes("UTF-8")), null, Charset
          .forName("UTF-8"), new MyFontProvider("C:\\Users\\rw\\Desktop\\ss.ttf"));
    } catch (Exception e) { 
   
      e.printStackTrace();
    } finally { 
   
      if (null != document) { 
   
        document.close();
      }
      if (null != writer) { 
   
        writer.close();
      }
    }
  }

未完待续…

今天的文章java.pdf_java提取pdf文件中某一页分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88600.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注