2015-09-29 1 views
0

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

После создания полей с аннотациями я могу искать позиции через объект AcroField и получать страницы и позиции.

public static List<FieldPosition> getPositions(PdfReader pdfReader, String name) { 
     AcroFields acroFields = pdfReader.getAcroFields(); 
     List<FieldPosition> fieldPositions = acroFields.getFieldPositions(name); 
     return fieldPositions; 
    } 

И вы можете нарисовать текст в позиции, как это:

public static void writeString(PdfReader pdfReader, PdfStamper pdfStamper, String name, String valueStr, Font fontType, float leftDiff, 
      float bottomDiff) throws IOException, DocumentException { 
     Phrase pagePhrase = new Phrase(valueStr, fontType); 

     float left; 
     float bottom; 
     List<FieldPosition> fieldPositions = getPositions(pdfReader, name); 
     if (fieldPositions != null) { 
      for (FieldPosition fieldPos : fieldPositions) { 
       left = fieldPos.position.getLeft() + leftDiff; 
       bottom = fieldPos.position.getBottom() + bottomDiff; 
       PdfContentByte cover = pdfStamper.getOverContent(fieldPos.page); 
       ColumnText.showTextAligned(cover, Element.ALIGN_LEFT, pagePhrase, left, bottom, 0); 
      } 
     } 
    } 

Вы можете проверить образец для создания поля форм здесь http://itextpdf.com/examples/iia.php?id=157 образец выше, используя простой IText API со столом и клеток (вы можете см. ячейку используется для получения прямоугольника для поля)

Я пытаюсь создать те же поля двумя способами. Создать процессор для ячейки (TD) или для поля (вход или любой другой)

TagProcessorFactory tagProcessorFactory = Tags.getHtmlTagProcessorFactory(); 
tagProcessorFactory.addProcessor(new XHTMLTableTagProcessor(), new String[] { "table" }); 
tagProcessorFactory.addProcessor(new XHTMLCellMarkTagProcessor(writer), new String[] { "td" }); 
tagProcessorFactory.addProcessor(new XHTMLInputMarkTagProcessor(writer), new String[] { "input" }); 
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null); 
htmlContext.setTagFactory(tagProcessorFactory); 

Сотовый процессор

public class XHTMLCellMarkTagProcessor extends AbstractTagProcessor { 

    private PdfWriter writer; 

    public XHTMLCellMarkTagProcessor(PdfWriter writer) { 
     this.writer = writer; 
    } 

    @Override 
    public List<Element> end(WorkerContext ctx, Tag tag, List<Element> currentContent) { 
     String mark = "mark"; 
     String strMark = tag.getAttributes().get(mark); 
     String strName = tag.getAttributes().get("name"); 

     boolean isMark = StringUtils.isAlpha(strMark) && strMark.equalsIgnoreCase("true"); 

     System.out.println(String.format(currentContent.size() + "<<< %s %s ", strName, strMark)); 

     List<Element> retval = super.end(ctx, tag, currentContent); 
     if (isMark && StringUtils.isNotBlank(strName)) { 
      for (Element element : retval) { 
       if (element instanceof PdfPCell) { 
        final TextField nameField = new TextField(writer, new Rectangle(0, 0, 1, 5), strName); 
        try { 

         final PdfFormField formField = nameField.getTextField(); 
         final int width = 1; 

         PdfPCellEvent cellEvent = new PdfPCellEvent() { 
          @Override 
          public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) { 
           try { 
            formField.setWidget(new Rectangle(position.getLeft(), position.getBottom(), position.getLeft() + width, 
              position.getTop()), PdfAnnotation.HIGHLIGHT_NONE); 
            writer.addAnnotation(formField); 
           } catch (Exception e) { 
            throw new RuntimeException(e); 
           } 
          } 
         }; 

         ((PdfPCell) element).setCellEvent(cellEvent); 

        } catch (Exception e) { 
         throw new RuntimeException(e); 
        } 
       } 
      } 
     } 

     return retval; 
    } 
} 

элементы всегда равны нулю, даже если родитель вызывается или нет, не существует процессора по умолчанию для таких ячеек, как таблицы или divs Получить ошибку: java.lang.IllegalArgumentException: количество столбцов в конструкторе PdfPTable должно быть больше нуля.

вход процессора

public class XHTMLInputMarkTagProcessor extends AbstractTagProcessor { 

    private PdfWriter writer; 

    public XHTMLInputMarkTagProcessor(PdfWriter writer) { 
     this.writer = writer; 
    } 

    @Override 
    public List<Element> start(final WorkerContext ctx, final Tag tag) { 
     List<Element> elements = super.start(ctx, tag); 
     try { 
      String mark = "mark"; 
      String strMark = tag.getAttributes().get(mark); 
      String strType = tag.getAttributes().get("type"); 
      String strName = tag.getAttributes().get("name"); 
      String strSize = tag.getAttributes().get("size"); 
      String strValue = tag.getAttributes().get("value"); 

      boolean isMark = StringUtils.isAlpha(strMark) && strMark.equalsIgnoreCase("true"); 
      int size = StringUtils.isNumeric(strSize) ? new Integer(strSize.trim()) : 0; 

      System.out.println(String.format("<<< %s %s %s %s %s", strName, strType, strMark, strSize, size)); 

      if (isMark && StringUtils.isNotBlank(strType) && strType.equals("text")) { 
       TextField nameField = new TextField(writer, new Rectangle(100, 100, 100, 50), strName); 
       nameField.setBackgroundColor(BaseColor.GREEN); 
       PdfFormField formField = nameField.getTextField(); 
       formField.setValueAsString(strValue); 
       formField.setWidget(new Rectangle(100, 100, 100, 100), PdfAnnotation.HIGHLIGHT_PUSH); 
       writer.addAnnotation(formField); 
       //System.out.println("ADDDD"); 
      } 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
     return elements; 
    } 
} 

Я не вижу ничего в результате PDF. Объект TextField, не могут быть добавлены в список элементов, поскольку не распространяется на элемент интерфейса

ответ

0

Решение использование тд TagProcessor расширение процессор TableData как это:

public class XHTMLCellMarkTagProcessor extends TableData { 

    private PdfWriter writer; 

    public XHTMLCellMarkTagProcessor(PdfWriter writer) { 
     this.writer = writer; 
    } 

    @Override 
    public List<Element> end(WorkerContext ctx, Tag tag, List<Element> currentContent) { 
     String mark = "mark"; 
     String strMark = tag.getAttributes().get(mark); 
     String strName = tag.getAttributes().get("name"); 
     boolean isMark = StringUtils.isAlpha(strMark) && strMark.equalsIgnoreCase("true"); 

     List<Element> retval = super.end(ctx, tag, currentContent); 

     if (isMark && StringUtils.isNotBlank(strName)) { 
      for (Element element : retval) { 
       if (element instanceof PdfPCell) { 
        final TextField namedField = new TextField(writer, new Rectangle(0, 0, 10, 5), strName); 
        try { 

         final PdfFormField formField = namedField.getTextField(); 
         final int width = 0; 

         PdfPCellEvent cellEvent = new PdfPCellEvent() { 
          @Override 
          public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvas) { 
           try { 
            formField.setWidget(new Rectangle(position.getLeft(), position.getBottom(), position.getLeft() + width, 
              position.getTop()), PdfAnnotation.HIGHLIGHT_NONE); 
            writer.addAnnotation(formField); 

           } catch (Exception e) { 
            throw new RuntimeException(e); 
           } 
          } 
         }; 

         ((PdfPCell) element).setCellEvent(cellEvent); 

        } catch (Exception e) { 
         throw new RuntimeException(e); 
        } 
       } 
      } 
     } 

     return retval; 
    } 
} 
Смежные вопросы