Таблица формата POI Apache Не показывает Общую строку

#xml #apache-poi #xssf

Вопрос:

у меня есть класс для создания отформатированной таблицы, используя приведенный ниже код :

 public class formatAsTable {

    public static void main(String[] args)
            throws FileNotFoundException, IOException {

        Workbook wb = new XSSFWorkbook();
        XSSFSheet sheet = (XSSFSheet) wb.createSheet();


        XSSFTable my_table = sheet.createTable();


        CTTable cttable = my_table.getCTTable();

        /* Let us define the required Style for the table */
        CTTableStyleInfo table_style = cttable.addNewTableStyleInfo();
        table_style.setName("TableStyleMedium9");


        table_style.setShowColumnStripes(false); //showColumnStripes=0
        table_style.setShowRowStripes(true); //showRowStripes=1


        AreaReference my_data_range = wb.getCreationHelper().createAreaReference(new CellReference(0, 0), new CellReference(4, 2));

        cttable.setRef(my_data_range.formatAsString());
        cttable.setDisplayName("MYTABLE");

        cttable.addNewAutoFilter();

        cttable.setName("Test");
        cttable.setId(1L);

        CTTableColumns columns = cttable.addNewTableColumns();
        columns.setCount(3L); //define number of columns

        for (int i = 0; i < 3; i  ) {
            CTTableColumn column = columns.addNewTableColumn();
            column.setName("Column"   i);
            column.setId(i   1);
        }

        /* Add And Show TotelRow */
        cttable.setTotalsRowShown(true);

        for (int x = 0; x < 3; x  ) {
            cttable.getTableColumns().getTableColumnArray(x).setId(x   1);

            switch (x) {
                case 0 ->
                    cttable.getTableColumns().getTableColumnArray(x).setTotalsRowLabel("Totales: ");
                default ->
                    cttable.getTableColumns().getTableColumnArray(x).setTotalsRowFunction(org.openxmlformats.schemas.spreadsheetml.x2006.main.STTotalsRowFunction.SUM);
            }
        }

        for (int i = 0; i <= 4; i  ) //we have to populate 4 rows
        {
            XSSFRow row = sheet.createRow(i);
            for (int j = 0; j < 3; j  ) //Three columns in each row
            {
                XSSFCell localXSSFCell = row.createCell(j);
                if (i == 0) {
                    localXSSFCell.setCellValue("Heading"   j);
                } else {
                    localXSSFCell.setCellValue(i   j);
                }
            }
        }

        FileOutputStream fileOut = new FileOutputStream("Excel_Format_As_Table.xlsx");
        wb.write(fileOut);
        fileOut.close();
    }
}
 

он работает нормально, но даже если я установлю cttable.setTotalsRowShown(true); он не показывает общую строку !

И я должен открыть файл и нажать на Общую строку в дизайне таблицы, чтобы сделать ее видимой :

введите описание изображения здесь

Я изменил название и содержимое и попытался добавить разные форматы, но безрезультатно

Комментарии:

1. Какую apache poi версию вы используете? В настоящее apache poi 5.0.0 время использование базового CT класса больше не требуется.

2. вместо этого я использовал XSSFTable, и в итоге у меня возникла та же проблема ! я думаю, что это 4.1.2

3. Я искал эту проблему снова и снова и не находил решения .. Есть ли решение этой проблемы ? Или это ошибка в POI ?

Ответ №1:

Основная проблема заключается в том, что он должен быть настроен CTTable.setTotalsRowCount(1) на отображение одной строки итогов. Ваше употребление CTTable.setTotalsRowShown(true) имеет другое значение.

В соответствии с атрибутом форматов файлов ECMA-376 Office Open XML totalsRowShown означает:

Логическое значение, указывающее, отображалась ли строка итогов когда-либо в прошлом для этой таблицы. Значение True, если была показана строка итогов, в противном случае значение false.

Но атрибут totalsRowCount означает:

Целое число, представляющее количество строк итогов, которые должны быть показаны в нижней части таблицы.

0 означает, что строка итогов не отображается. Приложение для работы с электронными таблицами должно определить, разрешены ли числа, превышающие 1. Если в приложении для работы с электронными таблицами нет функции, в которой их может быть более одной строки итогов, это число не должно превышать 1.

Но в Excel значениях и настройках для таблиц всегда необходимо синхронизировать настройки таблицы и лист, на котором присутствует таблица. В противном случае это не будет работать и даже может привести к повреждению рабочих книг. Таким образом, как и для строки заголовков, на листе также должна быть строка итогов. А значения и формулы в этой строке итогов на листе должны соответствовать настройкам таблицы.

Следующий полный пример показывает все это. Он использует классы высокого уровня apache poi , когда это возможно. Он протестирован и работает apache poi 5.0.0 как с использованием, так apache poi 4.1.2 и с помощью . Более низкие версии не поддерживаются, так как в них были ошибки при создании таблиц.

 import java.io.FileOutputStream;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;

class CreateExcelTable {

 public static void main(String[] args) throws Exception {

  try (XSSFWorkbook workbook = new XSSFWorkbook();
       FileOutputStream fileout = new FileOutputStream("Excel.xlsx") ) {

   //prepairing the sheet
   XSSFSheet sheet = workbook.createSheet();
   
   String[] tableHeadings = new String[]{"Heading1", "Heading2", "Heading3"};
   String tableName = "Table1";
   int firstRow = 0; //start table in row 1
   int firstCol = 0; //start table in column A
   int rows = 6; //we have to populate headings row, 4 data rows and 1 totals row
   int cols = 3; //three columns in each row
  
   for (int r = 0; r < rows; r  ) { 
    XSSFRow row = sheet.createRow(firstRow r);
    for (int c = 0; c < cols; c  ) { 
     XSSFCell localXSSFCell = row.createCell(firstCol c);
     if (r == 0) {
      localXSSFCell.setCellValue(tableHeadings[c]);
     } else if (r == 5) {
      //totals row content will be set later
     } else {
      localXSSFCell.setCellValue(r   c);
     }
    }
   }
   
   //create the table
   CellReference topLeft = new CellReference(sheet.getRow(firstRow).getCell(firstCol));
   CellReference bottomRight = new CellReference(sheet.getRow(firstRow rows-1).getCell(firstCol cols-1));
   AreaReference tableArea = workbook.getCreationHelper().createAreaReference(topLeft, bottomRight);
   XSSFTable dataTable = sheet.createTable(tableArea);
   dataTable.setName(tableName);
   dataTable.setDisplayName(tableName);

   //this styles the table as Excel would do per default
   dataTable.getCTTable().addNewTableStyleInfo();
   XSSFTableStyleInfo style = (XSSFTableStyleInfo)dataTable.getStyle();
   style.setName("TableStyleMedium9");
   style.setShowColumnStripes(false);
   style.setShowRowStripes(true);
   style.setFirstColumn(false);
   style.setLastColumn(false);

   //this sets auto filters
   dataTable.getCTTable().addNewAutoFilter().setRef(tableArea.formatAsString());
   
   //this sets totals properties to table and totals formulas to sheet
   XSSFRow totalsRow = dataTable.getXSSFSheet().getRow(tableArea.getLastCell().getRow());
   for (int c = 0; c < dataTable.getCTTable().getTableColumns().getTableColumnList().size(); c  ) {
    if (c == 0) {
     dataTable.getCTTable().getTableColumns().getTableColumnList().get(c).setTotalsRowLabel("Totals: ");
     totalsRow.getCell(tableArea.getFirstCell().getCol() c).setCellValue("Totals: ");
   } else {
     dataTable.getCTTable().getTableColumns().getTableColumnList().get(c).setTotalsRowFunction(org.openxmlformats.schemas.spreadsheetml.x2006.main.STTotalsRowFunction.SUM); 
     totalsRow.getCell(tableArea.getFirstCell().getCol() c).setCellFormula("SUBTOTAL(109,"   tableName   "["   tableHeadings[c]   "])");
    }
   }
   //this shows the totals row
   dataTable.getCTTable().setTotalsRowCount(1);

   workbook.write(fileout);
  }

 }
}
 

Использование всех org.openxmlformats.schemas.spreadsheetml.x2006.main.* классов необходимо ooxml-schemas-1.4.jar для apache poi 4.1.2 или poi-ooxml-full-5.0.0.jar для apache poi 5.0.0 . Легкие версии ooxml не содержат всех классов. Видишь https://poi.apache.org/help/faq.html#faq-N10025