PDFBOX 2.0+ java Свести аннотации freetext созданный foxit - PullRequest
0 голосов
/ 09 апреля 2020

Я столкнулся с очень сложной проблемой. У нас есть формы, которые должны были быть заполнены, но некоторые люди использовали текстовые комментарии в форме аннотации в foxit вместо заполнения полей формы, поэтому аннотации никогда не сглаживаются. Когда наше программное обеспечение рендеринга генерирует окончательный документ, аннотации не включаются.

Решение, которое я попробовал, состоит в том, чтобы в основном go просмотреть документ, получить текстовое содержание аннотации и записать его в pdf, чтобы он был в конечном документе, затем удалить фактическую аннотацию, но я столкнулся с проблемой где я не знаю, какой шрифт использует аннотация, межстрочный интервал и т. д. c, поэтому я не могу узнать, как получить его из pdfbox для точного воссоздания, когда аннотация выглядит на неоткрытой форме. По сути, я хочу сгладить аннотации произвольной формы, созданные в foxit (функция комментариев пишущей машинки). Вот код. Это работает, но я снова пытаюсь понять, как получить аннотации для записи в мой окончательный PDF-документ. Опять сглаживать на акроформе не работает, потому что это не поля акроформы! Живой код отфильтровывает все, что не является аннотацией типа свободного текста, но приведенный ниже код должен показать мою проблему.

    public static void main(String [] args)
{
        String startDoc = "C:/test2/test.pdf";
     String  finalFlat = "C:/test2/test_FLAT.pdf";

    try {
        // for testing
        try {
            //BasicConfigurator.configure();
            File myFile = new File(startDoc);
            PDDocument pdDoc = PDDocument.load( myFile );
            PDDocumentCatalog pdCatalog = pdDoc.getDocumentCatalog();
            PDAcroForm pdAcroForm = pdCatalog.getAcroForm();

            // set the NeedApperances flag
            pdAcroForm.setNeedAppearances(false);

            // correct the missing page link for the annotations
            for (PDPage page : pdDoc.getPages()) {

                for (PDAnnotation annot : page.getAnnotations()) {
                    System.out.println(annot.getContents());
                    System.out.println(annot.isPrinted());
                    System.out.println(annot.isLocked());

                    System.out.println(annot.getAppearance().toString());
                    PDPageContentStream contentStream = new PDPageContentStream(pdDoc, page, PDPageContentStream.AppendMode.APPEND,true,true);
                    int fontHeight = 14; 
                    contentStream.setFont(PDType1Font.TIMES_ROMAN, fontHeight);

                    float height = annot.getRectangle().getLowerLeftY();

                    String s  = annot.getContents().replaceAll("\t", "    ");

                    String ss[] = s.split("\\r");
                    for(String sss : ss)
                    {
                        contentStream.beginText();  
                        contentStream.newLineAtOffset(annot.getRectangle().getLowerLeftX(),height );
                      contentStream.showText(sss);
                      height = height + fontHeight * 2 ;

                      contentStream.endText();
                    }
                      contentStream.close();
                    page.getAnnotations().remove(annot);                    
                }
            }               
            pdAcroForm.flatten();
            pdDoc.save(finalFlat);
            pdDoc.close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }   

    }
    catch (Exception e) {
        System.err.println("Exception: " + e.getLocalizedMessage());
    }
}

1 Ответ

1 голос
/ 09 апреля 2020

Это было не весело. После миллиона различных тестов, и я все еще не понимаю всех нюансов, но эта версия призвана сгладить все PDF-файлы и аннотации, если они видны в PDF. Протестировано около полдюжины создателей PDF, и если на странице видна аннотация, то, надеюсь, это сгладит ее. Я подозреваю, что есть лучший способ, потянув матрицу и преобразовав ее, а что нет, но это единственный способ заставить его работать везде.

public static void flattenv3(String startDoc, String endDoc) {

  org.apache.log4j.Logger.getRootLogger().setLevel(org.apache.log4j.Level.INFO);
  String finalFlat = endDoc;


  try {

   try {
    //BasicConfigurator.configure();
    File myFile = new File(startDoc);
    PDDocument pdDoc = PDDocument.load(myFile);
    PDDocumentCatalog pdCatalog = pdDoc.getDocumentCatalog();
    PDAcroForm pdAcroForm = pdCatalog.getAcroForm();

    if (pdAcroForm != null) {
     pdAcroForm.setNeedAppearances(false);
     pdAcroForm.flatten();
    }

    // set the NeedApperances flag

    boolean isContentStreamWrapped;
    int ii = 0;

    for (PDPage page: pdDoc.getPages()) {
     PDPageContentStream contentStream;
     isContentStreamWrapped = false;
     List < PDAnnotation > annotations = new ArrayList < > ();

     for (PDAnnotation annotation: page.getAnnotations()) {



      if (!annotation.isInvisible() && !annotation.isHidden() && annotation.getNormalAppearanceStream() != null)

      {
       ii++;
       if (ii > 1) {
        // contentStream.close();
        // continue;

       }


       if (!isContentStreamWrapped) {
        contentStream = new PDPageContentStream(pdDoc, page, AppendMode.APPEND, true, true);
        isContentStreamWrapped = true;
       } else {
        contentStream = new PDPageContentStream(pdDoc, page, AppendMode.APPEND, true);
       }

       PDAppearanceStream appearanceStream = annotation.getNormalAppearanceStream();

       PDFormXObject fieldObject = new PDFormXObject(appearanceStream.getCOSObject());

       contentStream.saveGraphicsState();


       boolean needsTranslation = resolveNeedsTranslation(appearanceStream);



       Matrix transformationMatrix = new Matrix();
       boolean transformed = false;

        float lowerLeftX = annotation.getNormalAppearanceStream().getBBox().getLowerLeftX();
        float lowerLeftY = annotation.getNormalAppearanceStream().getBBox().getLowerLeftY();
        PDRectangle bbox = appearanceStream.getBBox();
        PDRectangle fieldRect = annotation.getRectangle();

        float xScale = fieldRect.getWidth() - bbox.getWidth();

        transformed = true;

        lowerLeftX = fieldRect.getLowerLeftX();
        lowerLeftY = fieldRect.getLowerLeftY();
        if (bbox.getLowerLeftX() <= 0 && bbox.getLowerLeftY() < 0 && Math.abs(xScale) < 1) //BASICALLY EQUAL TO 0 WITH ROUNDING
        {


         lowerLeftY = fieldRect.getLowerLeftY() - bbox.getLowerLeftY();
         if (bbox.getLowerLeftX() < 0 && bbox.getLowerLeftY() < 0) //THis is for the o
         {

          lowerLeftX = lowerLeftX - bbox.getLowerLeftX(); 

         }

        } else if (bbox.getLowerLeftX() == 0 && bbox.getLowerLeftY() < 0 && xScale >= 0) {

         lowerLeftX = fieldRect.getUpperRightX();

        } else if (bbox.getLowerLeftY() <= 0 && xScale >= 0) {

         lowerLeftY = fieldRect.getLowerLeftY() - bbox.getLowerLeftY() - xScale;

        } else if (bbox.getUpperRightY() <= 0) {

         if (annotation.getNormalAppearanceStream().getMatrix().getShearY() < 0) {
          lowerLeftY = fieldRect.getUpperRightY();
          lowerLeftX = fieldRect.getUpperRightX();

         }

        } else {

        }



        transformationMatrix.translate(lowerLeftX,
         lowerLeftY);
        contentStream.transform(transformationMatrix);


       contentStream.drawForm(fieldObject);
       contentStream.restoreGraphicsState();
       contentStream.close();
      }
     }
     page.setAnnotations(annotations);
    }


    pdDoc.save(finalFlat);
    pdDoc.close();
    File file = new File(finalFlat);

    // Desktop.getDesktop().browse(file.toURI());


   } catch (Exception e) {
    e.printStackTrace();
   }

  } catch (Exception e) {
   System.err.println("Exception: " + e.getLocalizedMessage());
  }
 }

}

...