简体   繁体   English

在具有表的excel(xlsx)表中写入数据

[英]Write data in excel(xlsx) sheet having a table

I am trying to write dynamic data in an excel sheet (xlsx) having a table already created, based on which we plot a chart in excel itself, using a macro. 我正在尝试在已创建表的excel表(xlsx)中编写动态数据,基于此我们使用宏在Excel中绘制图表。

I am using POI to write the data. 我正在使用POI来编写数据。

The table in the sheet has been set to 10 rows. 工作表中的表已设置为10行。 When I write data for more than 10 rows, the table does not get expanded.So, the chart plotted contains data corresponding to 10 rows only. 当我写入超过10行的数据时,表格不会扩展。因此,绘制的图表包含仅对应10行的数据。

How can I write data, so that the data always expands the table to number of rows in the data? 如何编写数据,以便数据始终将表扩展为数据中的行数?

You should create an XSSFTable object from sheet.createTable(); 您应该从sheet.createTable();创建一个XSSFTable对象sheet.createTable(); .

Here's an example I found at http://thinktibits.blogspot.co.il/2014/09/Excel-Insert-Format-Table-Apache-POI-Example.html - just make sure the table created covers all the rows/columns you dynamically place in the file. 以下是我在http://thinktibits.blogspot.co.il/2014/09/Excel-Insert-Format-Table-Apache-POI-Example.html中找到的示例 - 只需确保创建的表格涵盖所有行/列你动态地放在文件中。

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.*;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFCell;
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 insertTable
{
  public static void main(String[] args)
    throws FileNotFoundException, IOException
  {
   /* Read the input file that contains the data to be converted to table */
   FileInputStream input_document = new FileInputStream(new File("FormatAsTable.xlsx"));    
   /* Create Workbook */
   XSSFWorkbook my_xlsx_workbook = new XSSFWorkbook(input_document); 
   /* Read worksheet */
   XSSFSheet sheet = my_xlsx_workbook.getSheetAt(0); 
   /* Create Table into Existing Worksheet */
   XSSFTable my_table = sheet.createTable();    
   /* get CTTable object*/
   CTTable cttable = my_table.getCTTable();
   /* Define Styles */    
   CTTableStyleInfo table_style = cttable.addNewTableStyleInfo();
   table_style.setName("TableStyleMedium9");           
   /* Define 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(0, 0), new CellReference(5, 2));    
   /* Set Range to the Table */
   cttable.setRef(my_data_range.formatAsString());
   cttable.setDisplayName("MYTABLE");      /* this is the display name of the table */
   cttable.setName("Test");    /* This maps to "displayName" attribute in <table>, OOXML */            
   cttable.setId(1L); //id attribute against table as long value
   /* Add header columns */               
   CTTableColumns columns = cttable.addNewTableColumns();
   columns.setCount(3L); //define number of columns
   /* Define Header Information for the Table */
    for (int i = 0; i < 3; i++)
    {
    CTTableColumn column = columns.addNewTableColumn();   
    column.setName("Column" + i);      
        column.setId(i+1);
    }   
    /* Write output as File */
    FileOutputStream fileOut = new FileOutputStream("Excel_Format_As_Table.xlsx");
    my_xlsx_workbook.write(fileOut);
    fileOut.close();
  }

While this question is a bit dated, it cost me more than 4 hours to figure this out, so I thought posting it might help. 虽然这个问题有点过时,但我花了4个多小时来解决这个问题,所以我认为发布它可能有所帮助。 This alters an existing table instead of creating a new one. 这会改变现有表而不是创建新表。

// tell your xssfsheet where its content begins and where it ends
((XSSFWorksheet) sheet).getCTWorksheet().getDimension()
    .setRef("A1:H" + (sheet.getLastRowNum() + 1));

CTTable ctTable = sheet.getTables().get(0).getCTTable();

ctTable.setRef("A1:H" + (sheet.getLastRowNum() + 1)); // adjust reference as needed

ctTable.unsetSortState(); // if you had sorted the data in Excel before reading the file,
                          // you may want an unsorted table in your output file

CTTableColumns ctColumns = ctTable.getTableColumns(); // setting new table columns will
                                                      // muck everything up, 
                                                      // so adjust the existing ones

// remove the old columns first if you plan on expanding your table in the column direction
for (int i = 0; i < ctColumns.getCount(); i++) {
    ctColumns.removeTableColumn(0);
}

// throw in your new columns
for (int i = 0; i < tableHeaders.size(); i++) {
    CTTableColumn column = ctColumns.addNewTableColumn();
    column.setName(tableHeaders.get(i));
    column.setId(i + 1);
}

// for some reason this isn't being take care of when columns are modified,
// so fix the column count manually
ctColumns.setCount(tableHeaders.size());

A word of warning: all the unsetX methods in CTTable will throw IndexOutOfBoundsException s if the respective property doesn't exist in the table, so they need to be try-catch-ed. 一句警告:如果表中不存在相应的属性, CTTable所有unsetX方法CTTable将抛出IndexOutOfBoundsException ,因此它们需要是try-catch-ed。 An alternative mentioned by @Gagravarr in the comments is to use isSetX first, then there's no need for try ing. @Gagravarr在评论中提到的另一种方法是首先使用isSetX ,然后就不需要try

If this doesn't work, then you probably have a bunch of other stuff set in your table. 如果这不起作用,那么你可能在表中设置了一堆其他东西。 Unfortunately, the low-level XML stuff (encapsulated in all those CT objects) is very poorly documented since it's apparently auto-generated from the spec, so the API is pretty opaque. 不幸的是,低级XML内容(封装在所有这些CT对象中)的文档很少,因为它显然是从规范自动生成的,因此API非常不透明。 The teeth-grinding process I go through to figure out what to use is to unpack the .xlsx, look at the XML I need to adjust, figure out where it lives in my XSSFSheet and how I need to adjust it, then go hunting for the suitable CT-methods, since the XSSF-API does not really let you do all that much. 我经历的磨牙过程是弄清楚要使用的是解压缩.xlsx,查看我需要调整的XML,找出它在我的XSSFSheet中的位置以及我需要如何调整它,然后去寻找合适的CT方法,因为XSSF-API并没有真正让你做那么多。 This way, you can create pretty much anything you would be able to create in Excel, and even alter some stuff you can't there - if you have the time and nerves. 通过这种方式,您可以创建几乎任何可以在Excel中创建的内容,甚至可以更改一些您不能在那里创建的内容 - 如果您有时间和紧张。

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

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