繁体   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