簡體   English   中英

使用PDFClown的展平表單拋出IndexOutOfBounds異常

[英]Flattening form using PDFClown throws IndexOutOfBounds exception

我正在使用PDFClown-0.2.0來展平 pdf文件。 這是我的代碼:

import org.pdfclown.documents.Document;
import org.pdfclown.files.File;
import org.pdfclown.files.SerializationModeEnum;
import org.pdfclown.tools.FormFlattener;

public class Sample {
    public static void main(String args[]){
        try {
            File f = new File("label.pdf");
            Document doc = f.getDocument();

            FormFlattener formFlattener = new FormFlattener();
            formFlattener.flatten(doc);
            f.save(SerializationModeEnum.Standard);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我正在按照http://pdfclown.org/2014/09/12/waiting-for-pdf-clown-0-2-0-release/#FormFlattening提供的說明進行操作。 但是,當我運行代碼時,出現以下錯誤:

java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at org.pdfclown.objects.PdfArray.get(PdfArray.java:314)
    at org.pdfclown.documents.interaction.forms.FieldWidgets.get(FieldWidgets.java:135)
    at org.pdfclown.documents.interaction.forms.FieldWidgets$1.next(FieldWidgets.java:380)
    at org.pdfclown.documents.interaction.forms.FieldWidgets$1.next(FieldWidgets.java:1)
    at org.pdfclown.tools.FormFlattener.flatten(FormFlattener.java:74)
    at com.narvar.webservices.returns.retailers.Sample.main(Sample.java:18)

我究竟做錯了什么? 請注意,pdf是使用PDFBox生成的,而我已將表單字段設置為只讀。

調試完代碼后,它看起來像是一個PdfClown錯誤:

org.pdfclown.documents.interaction.forms.FieldWidgets.iterator()返回的Iterator無法識別下方的小部件集合已更改(變小了),因此嘗試讀取超出其大小的內容。

詳細:

org.pdfclown.tools.FormFlattener.flatten(Document)遍歷字段的小部件:

  for(Widget widget : field.getWidgets())

但在此循環中,它將從當前字段的“ 孩子”中刪除當前小部件:

    // Removing the field references relating the widget...
    PdfDictionary fieldPartDictionary = widget.getBaseDataObject();
    while (fieldPartDictionary != null)
    {
      [...]
      kidsArray.remove(fieldPartDictionary.getReference());
      [...]
    }

因此, for外部迭代的集合會發生變化。 不幸的是,此處使用的Iterator並不了解基本集合中的更改

return new Iterator<Widget>()
{
  /** Index of the next item. */
  private int index = 0;
  /** Collection size. */
  private final int size = size();

  @Override
  public boolean hasNext( )
  {return (index < size);}

  @Override
  public Widget next( )
  {
    if(!hasNext()) throw new NoSuchElementException();
    return get(index++);
  }

  @Override
  public void remove( )
  {throw new UnsupportedOperationException();}
};

如您所見,它不僅不通知基礎集合,也不對其自身進行檢查,它甚至對集合大小有自己的想法,這是在Iterator生成時將size設置為size集合的size

對於可以通過體系結構或合同強制實施的不變集合,這樣的Iterator實現是可以的。 但是在這里的情況下,我看不到任何東西,該體系結構顯然允許更改集合,並且沒有暗示所討論的迭代器僅可用於穩定的基本集合。

這應該是固定的。

解決方案

可以通過更改FormFlattener.flatten來嘗試解決方案,以檢索小部件的本地副本並在該副本上進行迭代,例如通過替換

  for(Widget widget : field.getWidgets())

  List<Widget> widgets = new ArrayList<Widget>(field.getWidgets());
  for(Widget widget : widgets)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM