web-dev-qa-db-ja.com

ApachePOIでExcelドロップダウンリストを生成する際の制限

いくつかの検証を使用してExcelファイルを生成しようとしています。実装については、 poi dev guides を読みました。実装中に例外が発生しました(String literals in formulas can't be bigger than 255 characters ASCII)。 POIは、すべてのドロップダウンオプションを「0」のデリミテッド文字列に連結し、その長さをチェックして例外を与えます。 :(
POI3.8ベータ5の最新バージョンを使用しています。
そして私のコードは:

try {
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("new sheet");
    HSSFRow row = sheet.createRow((short) 0);
    //CellRangeAddressList from org.Apache.poi.ss.util package
    CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
    DVConstraint dvConstraint = DVConstraint.createExplicitListConstraint(getCountries());
    DataValidation dataValidation = new HSSFDataValidation(addressList, dvConstraint);
    dataValidation.setSuppressDropDownArrow(false);
    sheet.addValidationData(dataValidation);
    FileOutputStream fileOut = new FileOutputStream("c:\\test.xls");
    wb.write(fileOut);
    fileOut.close();
    } catch (IOException e) {
       e.printStackTrace();
  }

その後、次のコードを使用してXSSFWorkBookを試してみました。

XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet("new sheet");
DataValidationHelper validationHelper = new XSSFDataValidationHelper(sheet);
DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(getCountries());
CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
DataValidation dataValidation = validationHelper.createValidation(constraint, addressList);
dataValidation.setErrorStyle(DataValidation.ErrorStyle.STOP);
dataValidation.setSuppressDropDownArrow(true);
sheet.addValidationData(dataValidation);
FileOutputStream fileOut = new FileOutputStream("c:\\test.xlsx");

残念ながら、1つのセルに長い文字列をコンマで区切ったような結果では成功しません。

enter image description here

しかし、Excelで手動で、この長い国のリストを使用してドロップダウンセルを作成できます。
長い文字列でドロップダウンを生成する方法はありますか、またはAPIはサポートしていませんか?

13
Õzbek

私はそれを理解しました、Excel自体は255文字を超える検証範囲文字列を入力することを許可していません、これはPOIの制限ではありませんでした。そして今、私は 名前付き範囲と名前付きセル を使用していて、それは私にとって適切に機能しています。そのため、検証範囲トークンを別のシート(非表示にしたもの)に配置する必要があり、実際のシートから目的のセル範囲を参照しました。これが私の作業コードです:

HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet realSheet = workbook.createSheet("Sheet xls");
HSSFSheet hidden = workbook.createSheet("hidden");
for (int i = 0, length= countryName.length; i < length; i++) {
   String name = countryName[i];
   HSSFRow row = hidden.createRow(i);
   HSSFCell cell = row.createCell(0);
   cell.setCellValue(name);
 }
 Name namedCell = workbook.createName();
 namedCell.setNameName("hidden");
 namedCell.setRefersToFormula("hidden!$A$1:$A$" + countryName.length);
 DVConstraint constraint = DVConstraint.createFormulaListConstraint("hidden");
 CellRangeAddressList addressList = new CellRangeAddressList(0, 0, 0, 0);
 HSSFDataValidation validation = new HSSFDataValidation(addressList, constraint);
 workbook.setSheetHidden(1, true);
 realSheet.addValidationData(validation);
 FileOutputStream stream = new FileOutputStream("c:\\range.xls");
 workbook.write(stream);
 stream.close();
28
Õzbek

上記のコードは正常に機能します。しかし、HSSFの代わりにXSSFクラスを使用すると、スレッドで例外と表示されません。

"main" Java.lang.NoSuchMethodError: org.Apache.poi.ss.formula.FormulaParser.parse(Ljava/lang/String;Lorg/Apache/poi/‌​ss/formula/FormulaParsingWorkbook;II)[Lorg/Apache/poi/ss/formula/ptg/Ptg; at org.Apache.poi.xssf.usermodel.XSSFName.setRefersToFormula(XSSFName.Java:195) at XLDropdown.main(XLDropdown.Java:35)

XSSFインターフェイスを使用してドロップダウンリストを作成するには、次の場所で解決策を入手しました。

Apache poi XSSFインターフェースを使用してドロップダウンリストを作成します

2
Kaushik Lele

Õzbekが提供する手ごわいソリューションは、NPOIで問題なく動作するためにわずかな変更を加えるだけで済みます(.NETでC#を使用)。

これが私のコードで、C#コーダーの便宜のために提供されています。シートと位置要素を入力として受け取り、列に配置されている場合は複数のドロップダウンを処理することもできます。

public static void CreateDropDownListForExcel(this ISheet sheet, IList<string> dropDownValues, int startRow, int lastRow, int column) {
    if (sheet == null) {
        return;
    }

    //Create a hidden sheet on the workbook (using the column as an id) with the dropdown values
    IWorkbook workbook = sheet.Workbook;
    string dropDownName = sheet.SheetName + "DropDownValuesForColumn" + column;
    ISheet hiddenSheet = workbook.CreateSheet(dropDownName);
    for (int i = 0, length = dropDownValues.Count; i < length; i++) {
        string name = dropDownValues[i];
        IRow row = hiddenSheet.CreateRow(i);
        ICell cell = row.CreateCell(0);
        cell.SetCellValue(name);
    }

    //Create the dropdown using the fields of the hidden sheet
    IName namedCell = workbook.CreateName();
    namedCell.NameName = dropDownName;
    namedCell.RefersToFormula = (dropDownName + "!$A$1:$A$" + dropDownValues.Count);
    DVConstraint constraint = DVConstraint.CreateFormulaListConstraint(dropDownName);
    CellRangeAddressList addressList = new CellRangeAddressList(startRow, lastRow, column, column);
    HSSFDataValidation validation = new HSSFDataValidation(addressList, constraint);
    int hiddenSheetIndex = workbook.GetSheetIndex(hiddenSheet);
    workbook.SetSheetHidden(hiddenSheetIndex, SheetState.HIDDEN);

    //Add the Dropdown to the presenting sheet.
    sheet.AddValidationData(validation);
}
2
Marcel