#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