org.apache.xmlbeans.impl.values.XmlValueDisconnectedException при создании ConditionalFormattingRule - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь создать XSSFConditionalFormattingRule с 3-х цветной раскраской. Поэтому мне нужно также установить пороги. Однако после отладки я обнаружил, что каждый XSSFConditionalFormattingThreshold выбрасывает com.sun.jdi.InvocationException occurred invoking method. в свое свойство CTCfvo, но только после вызова rule.getColorScaleFormatting().setNumControlPoints(3);

Мой полный код такой:

CellRangeAddress[] regions = { CellRangeAddress.valueOf("Z2:Z" + (sheet.getLastRowNum() + 1)) };

XSSFConditionalFormattingRule rule = sheet.getSheetConditionalFormatting()
        .createConditionalFormattingColorScaleRule();

XSSFConditionalFormattingThreshold thresh5 = rule.getColorScaleFormatting().createThreshold();
thresh5.setRangeType(RangeType.NUMBER);
thresh5.setValue(0.05);
XSSFConditionalFormattingThreshold thresh10 = rule.getColorScaleFormatting().createThreshold();
thresh10.setRangeType(RangeType.NUMBER);
thresh10.setValue(0.10);
XSSFConditionalFormattingThreshold thresh15 = rule.getColorScaleFormatting().createThreshold();
thresh15.setRangeType(RangeType.NUMBER);
thresh15.setValue(0.15);

rule.getColorScaleFormatting().setNumControlPoints(3);
rule.getColorScaleFormatting()
        .setThresholds(new ConditionalFormattingThreshold[] { thresh5, thresh10, thresh15 });
XSSFColor colorGreen = new XSSFColor(IndexedColors.GREEN, colorMap);
XSSFColor colorYellow = new XSSFColor(IndexedColors.YELLOW, colorMap);
XSSFColor colorRed = new XSSFColor(IndexedColors.RED, colorMap);

rule.getColorScaleFormatting().setColors(new Color[] { colorGreen, colorYellow, colorRed });

sheet.getSheetConditionalFormatting().addConditionalFormatting(regions, rule);

И это сокращенная трассировка стека , которую я получаю при обработке кода выше:

org.apache.xmlbeans.impl.values.XmlValueDisconnectedException at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned (XmlObjectBase.java:1258) в org.apache.xmlbeans.impl.values.XmlObjectBase.newCursor (XmlObjectBase.java:286) в org.apache.xmlbeans.impl.values.XmlComplexContentImpl.arraySetterHelper (XmlComplexContentImpl.java:1124) в org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTColorScaleImpl.setCfvoArray (Неизвестно Источник) в org.apache.poi.xssf.usermodel.XSSFColorScaleFormatting.setThresholds (XSSFColorScaleFormatting.java:85)

Что вызывает ошибку, которую я вижу здесь? Это ошибка, когда я создаю XSSFConditionalFormattingThreshold? Или что-то совсем другое?


Я использую apache poi v4.0.0.

1 Ответ

1 голос
/ 06 мая 2019

Как указано в вопросе, единственные случаи этой ошибки были связаны с написанием книги дважды ( SO вопрос , bugzilla ). Так что мне стало интересно, что я делаю не так. Я понятия не имел, с чего начать, поскольку все, что связано с ошибкой, не имеет ничего общего с моей проблемой.

Мой первый взгляд был сделан на документацию void org.apache.poi.xssf.usermodel.XSSFColorScaleFormatting.setNumControlPoints(int num), в которой говорится следующее:

Устанавливает количество контрольных точек, используемых для сопоставления цветов. Должен обычно 2 или 3.

После обновления необходимо убедиться, что пороговое значение и цвет количество совпадений

Вторая часть привлекла мое внимание. Я думал что-то вроде:

Я создаю пороги прямо на ColorScaleFormatting с getColorScaleFormatting().createThreshold(). Так что, если setNumControlPoints() фактически сбрасывает все пороги, которые были ранее созданы?

И в этот момент я просто переместился на rule.getColorScaleFormatting().setNumControlPoints(3); до создания всего XSSFConditionalFormattingThreshold, и мой код работал нормально.

Взглянув на метод setNumControlPoints, мы можем увидеть это:

public void setNumControlPoints(int num) {
    while (num < _scale.sizeOfCfvoArray()) {
        _scale.removeCfvo(_scale.sizeOfCfvoArray()-1);
        _scale.removeColor(_scale.sizeOfColorArray()-1);
    }
    while (num > _scale.sizeOfCfvoArray()) {
        _scale.addNewCfvo();
        _scale.addNewColor();
    }
}

Это ясно говорит о том, что некоторые вещи могут быть удалены при вызове этого метода, хотя я не мог точно понять, каков начальный размер _scale.sizeOfCfvoArray() (я бы предположил 0). И из-за этого я не мог понять, как происходит удаление материала, потому что я создал 3 порога (_scale.sizeOfCfvoArray() должно быть 3), а затем я позвонил setNumControlPoints(3), чтобы у нас было num == _scale.sizeOfCfvoArray(), и я ничего не смог найти за то, что происходит в этом случае (похоже, полное удаление всего).

В заключение, setNumControlPoints(int num) всегда следует вызывать как первое после создания правила и перед созданием любых порогов.


Если кто-то может указать, почему все сбрасывается, если num == _scale.sizeOfCfvoArray(), не стесняйтесь комментировать или редактировать.

...