繁体   English   中英

JAVA APACHE-POI表

[英]JAVA APACHE-POI tables

在班级下面有这个类,它将成为循环的一部分,这将在excel工作表中添加许多表。

我的问题是,我想不通,如何制作格式化为formatAsTable样式的表以计算总计行中的值。 我输入了以下两行代码:

cttable.setTotalsRowShown(true);
cttable.setTotalsRowCount(1);

设置过滤器,但公式不存在。我知道我有字符串值,以后会更改这些值,但是这些不会出现问题。下面的完整代码,如果有人知道如何,请详细说明,因为我不知道如何。

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Random;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFTable;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTable;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumns;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableStyleInfo;

public class formatAsTable2
{
    public static void main(String[] args)
        throws FileNotFoundException, IOException, InvalidFormatException
    {
        String[][] multi = new String[][]{
            { "Advisor", "nonContactedUTD", "appointmentsUTD", "totalWorkLoad", "notResponsiveCalls", "successfulCalls", "totalCalls", "totalIncomingEmails", "totalCommunication", "emailsSent","offerLetters","appFees","deposits" },
            { "Sharon Brown", "42", "44", "86", "62", "27", "89", "21", "220", "131" , "0", "6", "2", "0" },
            { "Elena Soteriou", "40", "44", "NULL", "62", "27", "89", "21", "230", "131" , "0", "7", "2", "0" },
            { "Helen Christou","45", "44", "86", "62", "27", "89", "21", "210", "131" , "0", "8", "2", "0" },
            { "Maria Georgiou", "48", "44", "86", "NULL", "27", "89", "21", "240", "131" , "0", "45", "2", "0" }
    };
    //(indexes start from 0) areaStart should be added to arenaRow
    int rowStart = 1;   //From which row the table to start +1
    int columnStart = 1; // From which column the table to start first column value 0

    int len = multi.length;
    int wid = multi[0].length;

    int areaRow = len + rowStart; // how many rows the table has
    int areaColumn = wid + columnStart - 1; //how many columns the table has
                                            /* Start with Creating a workbook and worksheet object */

    InputStream inp = new FileInputStream("Excel_Format_As_Table.xlsx");

    XSSFWorkbook wb = (XSSFWorkbook)WorkbookFactory.create(inp);
    XSSFSheet sheet = (XSSFSheet)wb.getSheetAt(0);

    /* Create an object of type XSSFTable */
    XSSFTable my_table = sheet.createTable();


    XSSFCellStyle my_style_1 = wb.createCellStyle();
    XSSFCellStyle my_style_0 = wb.createCellStyle();
    my_style_1.setAlignment(HorizontalAlignment.CENTER);
    my_style_1.setVerticalAlignment(VerticalAlignment.CENTER);

    XSSFFont my_font = wb.createFont();
    my_font.setBold(true);
    my_style_1.setFont(my_font);
    my_style_0.setFont(my_font);

    /* get CTTable object*/
    CTTable cttable = my_table.getCTTable();
    cttable.setTotalsRowShown(true);
    cttable.setTotalsRowCount(1);

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

    /* Set Table Style Options */
    table_style.setShowColumnStripes(false); //showColumnStripes=0
    table_style.setShowRowStripes(true); //showRowStripes=1


                                         /* Define the data range including headers */
    AreaReference my_data_range = new AreaReference(new CellReference(rowStart, columnStart), new CellReference(areaRow, areaColumn));

    String randomCode = generateRandomChars();
    String wantedDisplayName = "MT_" + randomCode;
    String wantedName = "WN_" + randomCode;
    long id = 4L;



    java.util.List<XSSFTable> all_tables = sheet.getTables();

    for (XSSFTable a_table : all_tables) {

        if (wantedDisplayName.equals(a_table.getDisplayName())) wantedDisplayName += "_1";
        if (wantedName.equals(a_table.getName())) wantedName += "_1";
        if (a_table.getCTTable().getId() > id) id = a_table.getCTTable().getId();

        // System.out.println(wantedDisplayName);
        // System.out.println(wantedName);
        // System.out.println(id);
    }
    id++;
    cttable.setRef(my_data_range.formatAsString());
    cttable.setDisplayName(wantedDisplayName);      /* this is the display name of the table */
    cttable.setName(wantedName);    /* This maps to "displayName" attribute in <table>, OOXML */
    cttable.setId(id); //id attribute against table as long value
    cttable.addNewAutoFilter();

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

                                  /* Define Header Information for the Table */
    for (int i = columnStart; i <= areaColumn; i++)
    {
        CTTableColumn column = columns.addNewTableColumn();

        column.setName("Column" + i);
        column.setId(i + 1);
    }
    int x = -1;
    int y = -1;

    /* Add remaining Table Data */

    XSSFRow rowDate = sheet.createRow(rowStart - 1);
    XSSFCell dateCell = rowDate.createCell(0);
    dateCell.setCellValue("Date");
    dateCell.setCellStyle(my_style_0);

    for (int i = rowStart; i<areaRow; i++) //we have to populate 4 rows
    {
        ++x;
        y = -1;
        /* Create a Row */
        XSSFRow row = sheet.createRow(i);
        for (int j = columnStart; j <= areaColumn; j++) //Three columns in each row
        {
            ++y;

            XSSFCell localXSSFCell = row.createCell(j);
            if (i == rowStart)
            {
                localXSSFCell.setCellValue(multi[x][y]);
            }
            else
            {
                localXSSFCell.setCellValue(multi[x][y]);
            }

        }
        XSSFRow rowx = sheet.createRow(i + 1);
        XSSFCell cellx = rowx.createCell(1);
        cellx.setCellValue("Total");
        //cellx = rowx.createCell(2);
        //cellx.setCellFormula("SUM(C3:C6)");



        cttable.setTotalsRowShown(true);
        cttable.setTotalsRowCount(1);

    }
    XSSFRow rowDateValue = sheet.getRow(rowStart);
    XSSFCell dateCellValue = rowDateValue.createCell(0);
    dateCellValue.setCellValue("24/02/2017");
    dateCellValue.setCellStyle(my_style_1);

    sheet.addMergedRegion(new CellRangeAddress(
        rowStart, // mention first row here
        multi.length + rowStart, //mention last row here, it is 4 as we are doing a row wise merging
        0, //mention first column of merging
        0  //mention last column to include in merge
    ));

    System.out.println("X" + x);
    System.out.println("y" + y);

    my_table.updateReferences();

    inp.close();
    /* Write output as File */
    FileOutputStream fileOut = new FileOutputStream("Excel_Format_As_Table.xlsx");
    wb.write(fileOut);
    fileOut.close();

    }
        public static String generateRandomChars() {

        String candidateChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
        int length = 17;

        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(candidateChars.charAt(random.nextInt(candidateChars
                .length())));
        }

        return sb.toString();
    }
}

主要问题是,必须将TotalsRowFunctionTotalsRowFunction以及单元格公式设置为总计行单元格。 如果未设置,则可以通过在总计行单元格中单击来选择Excel的总计行功能,然后从下拉列表中选择功能。

但是在将单元格公式设置为总计行单元格之前,我们必须解决代码的其他多个问题。

所有代码示例都是对您提供的代码的更改或补充:

我们应该使表显示名称和表名称相等。 这是因为显示名称在Excel中使用,但是apache poi的公式评估程序使用该名称。

...
    id++;
    cttable.setRef(my_data_range.formatAsString());
    cttable.setDisplayName(wantedDisplayName);      /* this is the display name of the table */
    cttable.setName(wantedDisplayName);    /* This maps to "displayName" attribute in <table>, OOXML */
    cttable.setId(id); //id attribute against table as long value
    cttable.addNewAutoFilter();
...

我们不仅应将所有列命名为“ Column ...”,还应使用正确的名称命名。 这是因为apache poi公式评估程序需要正确的名称来评估结构化参考公式。

...
    /* Define Header Information for the Table */
    for (int i = columnStart; i <= areaColumn; i++)
    {
        CTTableColumn column = columns.addNewTableColumn();
        column.setName(multi[0][i-1]);
        column.setId(i + 1);
        column.setTotalsRowFunction(org.openxmlformats.schemas.spreadsheetml.x2006.main.STTotalsRowFunction.SUM);
    }
...

在这里, TotalsRowFunction已经设置为SUM

对于使用org.openxmlformats.schemas.spreadsheetml.x2006.main.STTotalsRowFunction此示例需要FAQ-N10025中提到的所有ooxml-schemas-1.3.jar模式的完整jar。

现在,我们可以将单元格公式设置为总计行单元格作为结构化参考公式。

...
        XSSFRow rowx = sheet.createRow(i + 1);
        XSSFCell cellx = rowx.createCell(1);
        cellx.setCellValue("Total");
        for (int j = columnStart+1 ; j <= areaColumn; j++) 
        {
            cellx = rowx.createCell(j);
            cellx.setCellFormula("SUBTOTAL(109," + wantedDisplayName + "[" + multi[0][j-1] + "])");
        }
...

SUBTOTAL(109,... )为SUM设置。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM