Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ApachePOI在Excel中扩展现有表_Java_Excel_Apache Poi - Fatal编程技术网

Java 使用ApachePOI在Excel中扩展现有表

Java 使用ApachePOI在Excel中扩展现有表,java,excel,apache-poi,Java,Excel,Apache Poi,我有一个excel表格,里面有我想添加数据的公式 我这样做的动机是excel中的表可以动态扩展到您添加到其中的数据范围,这意味着公式行会自动跟上数据行的数量 但是,我很难确定使用ApachePOI是否可以实现这一点 我要尝试的一件事(见下面的代码)是扩展表的AreaReference,以覆盖数据,但是AreaReference(CR,CR2)(如示例中所用)和区域参考(CR、CR2、SpreadsheetVersion.EXCEL2007)(见apache)给出“构造函数未定义” 不知道是什么

我有一个excel表格,里面有我想添加数据的公式

我这样做的动机是excel中的表可以动态扩展到您添加到其中的数据范围,这意味着公式行会自动跟上数据行的数量

但是,我很难确定使用ApachePOI是否可以实现这一点

我要尝试的一件事(见下面的代码)是扩展表的
AreaReference
,以覆盖数据,但是
AreaReference(CR,CR2)(如示例中所用)和
区域参考(CR、CR2、SpreadsheetVersion.EXCEL2007)
(见apache)给出“构造函数未定义”

不知道是什么导致了构造函数错误,因为我已经导入了
org.apache.poi.ss.util

ApacheDocs
AreaReference(java.lang.String reference)
上的另一个选项允许我编译和运行,但给出了一个“NoSuchMethod”错误

List tableList=spreadSheet.getTables();
CellReference CR=新的CellReference(0,0);
CellReference CR2=新的CellReference(5,2);
AreaReference my_data_range=新的AreaReference(CR,CR2);
tableList.get(0).setArea(我的数据范围);

任何帮助都将不胜感激。

到目前为止,使用
ApachePOI
的主要问题是,如果不详细了解
Microsoft Office
本身以及
Microsoft Office
文件的存储,就无法使用它。很多事情只准备了一半,在新版本中经常会出现倒退(已经解决的bug再次出现)

因此,您的需求:“使用ApachePOI扩展Excel中的现有表”不仅仅是使用
ApachePOI
就可以实现。您必须知道,
officeopenxml
文件
*.xlsx
只是可以解压缩的
ZIP
归档文件。解压后,我们会找到存储表的
/xl/tables/table1.xml
。这个
XML
我们可以将其与使用
Excel
GUI
创建的
XML
进行分析和比较。因此,我们可以发现由
apachepoi
的缺点导致的问题。在
/xl/tables/sheet1.XML
中,工作表的
XML
也是如此

我们还需要知道,
apachepoi
构建在
ooxml模式的低级类上。部分地,我们需要使用这些类,因为
apachepoi
已经准备就绪了一半。在下面的示例中,我们还需要
ooxml-schemas-1.4.jar
,因为
apache-poi
poi-ooxml-schemas-4.0.0.jar
到目前为止还没有包含
org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableFormula
。不幸的是,目前还没有关于
ooxml模式的公开文档。因此,我们需要下载源代码并自己做
javadoc

下面的示例适用于我,使用的是
ApachePOI4.0.0
。如果在编译或运行时遇到问题,原因可能是编译时和/或运行时类路径中存在多个不同版本的
apache poi
jar
s。另外,正如前面所说,我的代码需要

import org.apache.poi.ss.usermodel.*;
导入org.apache.poi.xssf.usermodel.*;
导入org.apache.poi.ss.util.*;
导入org.apache.poi.ss.SpreadsheetVersion;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;
类扩展表{
静态void addrowtable(XSSFTable表){
int lastTableRow=table.getEndCellReference().getRow();
int totalsRowCount=table.getTotalsRowCount();
int lastTableDataRow=lastTableRow-totalsRowCount;
//我们将在表数据中添加一行
lastTableRow++;
lastTableDataRow++;
//新表区加一行
AreaReference newTableArea=新区域参考(
表.getStartCellReference(),
新细胞参考(
最后一行,
table.getEndCellReference().getCol()
),
电子表格版本.EXCEL2007
);
//新表数据区加一行
AreaReference newTableDataArea=新的AreaReference(
表.getStartCellReference(),
新细胞参考(
lastTableDataRow,
table.getEndCellReference().getCol()
),
电子表格版本.EXCEL2007
);
XSSFSheet sheet=table.getXSSFSheet();
如果(totalsRowCount>0){
//如果有总计行,请向下移动总计行
sheet.shiftRows(lastTableDataRow,lastTableRow,1);
//修正shiftRows不调整单元格引用的错误
//如果第3行下移,则单元格中的引用保持r=“A3”,r=“B3”。。。
//必须将它们调整到新的行中:r=“A4”,r=“B4”。。。
//ApachePOI3.17已经正确地做到了这一点,但在shiftRows中还有其他缺陷。
对于(int r=lastTableDataRow;r        List<XSSFTable> tableList = spreadSheet.getTables();
        CellReference CR = new CellReference(0, 0); 
        CellReference CR2 = new CellReference(5, 2);
        AreaReference my_data_range = new AreaReference(CR,CR2);
        tableList.get(0).setArea(my_data_range);
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTTableColumn;

class ExcelExpandingTable {

 static void addRowToTable(XSSFTable table) {

   int lastTableRow = table.getEndCellReference().getRow();
   int totalsRowCount = table.getTotalsRowCount();
   int lastTableDataRow = lastTableRow - totalsRowCount;

   // we will add one row in table data
   lastTableRow++;
   lastTableDataRow++;

   // new table area plus one row
   AreaReference newTableArea = new AreaReference(
                                 table.getStartCellReference(), 
                                 new CellReference(
                                  lastTableRow, 
                                  table.getEndCellReference().getCol()
                                 ),
                                 SpreadsheetVersion.EXCEL2007
                                );

   // new table data area plus one row
   AreaReference newTableDataArea = new AreaReference(
                                     table.getStartCellReference(), 
                                      new CellReference(
                                       lastTableDataRow, 
                                       table.getEndCellReference().getCol()
                                      ),
                                      SpreadsheetVersion.EXCEL2007
                                    );

   XSSFSheet sheet = table.getXSSFSheet();
   if (totalsRowCount > 0) {
    //if we have totals rows, shift totals rows down
    sheet.shiftRows(lastTableDataRow, lastTableRow, 1);

    // correcting bug that shiftRows does not adjusting references of the cells
    // if row 3 is shifted down, then reference in the cells remain r="A3", r="B3", ...
    // they must be adjusted to the new row thoug: r="A4", r="B4", ...
    // apache poi 3.17 has done this properly but had have other bugs in shiftRows.
    for (int r = lastTableDataRow; r < lastTableRow + 1; r++) {
     XSSFRow row = sheet.getRow(r); 
     if (row != null) {
      long rRef = row.getCTRow().getR();
      for (Cell cell : row) {
       String cRef = ((XSSFCell)cell).getCTCell().getR();
       ((XSSFCell)cell).getCTCell().setR(cRef.replaceAll("[0-9]", "") + rRef);
      }
     }
    }
    // end correcting bug

   }

   // if there are CalculatedColumnFormulas do filling them to the new row
   XSSFRow row = sheet.getRow(lastTableDataRow); if (row == null) row = sheet.createRow(lastTableDataRow);
   for (CTTableColumn tableCol : table.getCTTable().getTableColumns().getTableColumnList()) {
    if (tableCol.getCalculatedColumnFormula() != null) {
     int id = (int)tableCol.getId();
     String formula = tableCol.getCalculatedColumnFormula().getStringValue();
     XSSFCell cell = row.getCell(id -1); if (cell == null) cell = row.createCell(id -1);
     cell.setCellFormula(formula);
    }
   }

   table.setArea(newTableArea);

   // correcting bug that Autofilter includes possible TotalsRows after setArea new
   // Autofilter must only contain data area
   table.getCTTable().getAutoFilter().setRef(newTableDataArea.formatAsString());
   // end correcting bug

   table.updateReferences();

 }

 public static void main(String[] args) throws Exception {
  try (Workbook workbook = WorkbookFactory.create(new FileInputStream("SAMPLE.xlsx"));
       FileOutputStream out = new FileOutputStream("SAMPLE_NEW.xlsx")) {

   XSSFSheet sheet = ((XSSFWorkbook)workbook).getSheetAt(0);
   XSSFTable table = sheet.getTables().get(0);

   addRowToTable(table);

   workbook.write(out);
  } 
 }
}