poi的XSSFWorkbook转SXSSFWorkbook发现的问题
Posted CS_草祭先生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poi的XSSFWorkbook转SXSSFWorkbook发现的问题相关的知识,希望对你有一定的参考价值。
1. 背景
项目上需要对报表进行打印,前提是用户自己上传excel模板,设置页眉页脚及表格样式,由后端根据参数获取模板后和数据后,将数据写入excel中返回给前端转为pdf预览及打印。已有接口是用poi的SXSSFWorkbook操作excel,具体实现这篇文章已经说明。
现在需求变更,需要根据用户在模板中设置的表达式,将数据继承模板中样式输出到excel表格中。这样能让用户自定义设置表格样式,而非系统给定默认样式。
2. 遇到的问题
实现过程中,需要获取模板中已设置的excel,并循环所有行找到表达式填充数据。通过SXSSFWorkbook无法直接将流转换,只能先转换为XSSFWorkbook,再实例化SXSSFWorkbook。具体请看上面提到的文章内容
XSSFWorkbook workbook = new XSSFWorkbook(file1);
// 转换为SXSSFWorkbook
SXSSFWorkbook wbook = new SXSSFWorkbook(workbook);
使用wbook.getSheetAt(0).getLastRowNum()却无法获取模板中设置的最后行号。查看源码
public SXSSFWorkbook(XSSFWorkbook workbook)
this(workbook, DEFAULT_WINDOW_SIZE);
而使用workbook.getSheetAt(0).getLastRowNum()却能获取到。
而且有点难受的是,使用wbook.getSheetAt(0).getRow(0)获取到的为null,而使用wbook.getSheetAt(0).createRow(0)想去创建新行覆盖的时候又抛出异常,原因看以下源码
/**
* Create a new row within the sheet and return the high level representation
*
* @param rownum row number
* @return high level Row object representing a row in the sheet
* @throws IllegalArgumentException If the max. number of rows is exceeded or
* a rownum is provided where the row is already flushed to disk.
* @see #removeRow(Row)
*/
@Override
public SXSSFRow createRow(int rownum)
int maxrow = SpreadsheetVersion.EXCEL2007.getLastRowIndex();
if (rownum < 0 || rownum > maxrow)
throw new IllegalArgumentException("Invalid row number (" + rownum
+ ") outside allowable range (0.." + maxrow + ")");
// attempt to overwrite a row that is already flushed to disk
if(rownum <= _writer.getLastFlushedRow() )
throw new IllegalArgumentException(
"Attempting to write a row["+rownum+"] " +
"in the range [0," + _writer.getLastFlushedRow() + "] that is already written to disk.");
// attempt to overwrite a existing row in the input template
if(_sh.getPhysicalNumberOfRows() > 0 && rownum <= _sh.getLastRowNum() )
throw new IllegalArgumentException(
"Attempting to write a row["+rownum+"] " +
"in the range [0," + _sh.getLastRowNum() + "] that is already written to disk.");
SXSSFRow newRow = new SXSSFRow(this);
_rows.put(rownum, newRow);
allFlushed = false;
if(_randomAccessWindowSize >= 0 && _rows.size() > _randomAccessWindowSize)
try
flushRows(_randomAccessWindowSize);
catch (IOException ioe)
throw new RuntimeException(ioe);
return newRow;
代码走到第三个if的时候被逮住住抛出异常,真正有数据的是_sh,而不是_rows。但代码又不能获取到_sh
吐槽一下:无法理解写这个工具类的开发是怎么思考问题的,既让我们用,用起来又很难受
3. 解决方案
如果没有版本要求,时间也不够充裕,还是降低版本,使用XSSFWorkbook操作excel吧,懒得去纠结了,更有可能需要降低到HSSFWorkbook。反正操作方式基本相同,只是兼容的excel有些出入而已。
如果一定需要使用SXSSFWorkbook,那就去研究研究代码,看看如何解决这些问题。本人迫于时间紧任务重,只能委曲求全降低版本先实现功能了。
使用最新的POI3.11时,在运行 XSSFWorkbook workBook = new XSSFWorkbook ();这段代码时出现错误:
使用最新的POI3.11时,在运行
XSSFWorkbook workBook = new XSSFWorkbook ();这段代码时出现错误:
XMLEventFactory.newFactory()这个API是在JDK 1.6.0.18加入的,我当时是用MyEclipse 10运行编译的,而
MyEclipse 10 会用自带的jdk编译,而自带的是 1.6.0.13;
然后我把MyEclipse 的jdk环境设置成了1.7不用默认的jdk编译;问题得到解决;
以上是关于poi的XSSFWorkbook转SXSSFWorkbook发现的问题的主要内容,如果未能解决你的问题,请参考以下文章
Java-API-POI-Excel:XSSFWorkbook Documentation
收藏poi 使用模板创建一个XSSFWorkbook,为啥取不到row对象
org.apache.poi.hssf.usermodel.HSSFWorkbookorg.apache.poi.xssf.usermodel.XSSFWorkbook excel2003 exce
使用POI操作Excel时new XSSFWorkbook ()报错java.lang.NoSuchMethodError解决方式