以下代码是一个创建xlsx blob的测试程序 使用Apache POI并解压缩blob(xlsx是zip格式) 检查一些值。该代码基于Stack Overflow 问题,但我无法解压缩工作 正常。对此的要求是文件系统不能 感动,所以我们诉诸溪流。
问题在于行
int size = (int) entry.getSize();
总是产生-1。但是,请参阅
之前的评论zipInput.closeEntry();
对于进一步进入该计划的变化,但似乎 不正确。
我们不想使用POI本身来读取xlsx文件 因为我们正在测试POI似乎不存在的问题 与Apache Struts合作,我们希望消除 我们使用独立于Struts的POI的方式 是罪魁祸首。一旦这个测试通过,如果问题Struts 报告仍然存在,我们知道要看Struts本身而不是 我们使用POI的方式。
/**
* Short, Self Contained, Correct Example of
* 1) creating an xlsx blob with test data;
* 2) sending it to a stream;
* 3) unzipping the xlsx;
* 4) checking the worksheet's xml file for
* correct test values.
* Heavily inlined from two other properly factored
* files, one POI wrapper and one JUnit test case
* (although the test is not a "unit test" since it
* only tests third party library integration)
* DEPENDENCIES
* 1) poi-3.8.jar
* 2) poi-ooxml-3.8.jar
* 3) xmlbeans-2.6.0.jar
* 4) dom4j-1.6.1.jar
* 5) poi-ooxml-schemas-3.8.jar
* Other solutions attempted:
* 1) commons-compress: always returned byte array of proper size
* but containing all zeros.
* Note that we do NOT want to use the filesystem. This exercise's
* purpose is to create dynamically generated xlsx files delivered
* via HTTP. The filesystem is never involved.
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class CreateWorkbook
{
public static void main(String[] args) throws IOException
{
// create the data to place into workbook
List<List<String>> resultset = new ArrayList<List<String>>();
List<String> row = new ArrayList<String>();
row.add("A1");
row.add("B1");
row.add("C1");
resultset.add(row);
row = new ArrayList<String>();
row.add("A2");
row.add("B2");
row.add("C2");
resultset.add(row);
row = new ArrayList<String>();
row.add("A3");
row.add("B3");
row.add("C3");
resultset.add(row);
// create POI workbook and fill it with resultSet
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet s = workbook.createSheet();
for (int i = 0; i < resultset.size(); i++)
{
List<String> record = resultset.get(i);
Row r = s.createRow(i);
for (int j = 0; j < record.size(); j++)
r.createCell(j).setCellValue(record.get(j));
}
ByteArrayOutputStream out = new ByteArrayOutputStream();
workbook.write(out);
out.flush();
// retrieve workbook's data into a string and
// test if the cell values (a1,b2,c3,etc) appear
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
// xlsx is a zipped archive so we need to unzip
ZipInputStream zipInput = new ZipInputStream(in);
assert zipInput.available() == 1;
ZipEntry entry = zipInput.getNextEntry();
assert entry != null;
while (entry != null)
{
// since this "if" condition passes during execution we
// know that the stream contains a zip archive with
// an entry called "xl/worksheets/sheet1.xml". Therefore,
// ZipEntry retrieval appears to work correctly and the
// archive has at least a partially correct zip format.
if (entry.getName().equals("xl/worksheets/sheet1.xml"))
{
int size = (int) entry.getSize();
// ==============================================
// always fails, reports -1
assert size > 0 : size;
// ==============================================
byte[] bytes = new byte[size];
int readbytes = zipInput.read(bytes, 0, size);
assert readbytes > 0 : readbytes;
// nothing after this line has been tested
StringBuilder builder = new StringBuilder();
for (int i = 0; i < size; i++)
builder.append(Character.toString((char) bytes[i]));
String xml = builder.toString();
assert xml.contains("A1");
assert xml.contains("B2");
assert xml.contains("C3");
break;
}
// Swapping the order of these two lines actually
// causes the program to go further, with size = 678
// and failing at the readbytes assertion rather than
// the size assertion.
// I thought swapping would mess everything up since
// the entry would be closed immediately after obtaining
// it.
zipInput.closeEntry();
entry = zipInput.getNextEntry();
}
zipInput.close();
in.close();
}
}
答案 0 :(得分:1)
你并不完全适合使用Zip。
试试这个代码段:
if (entry.getName().equals("xl/worksheets/sheet1.xml"))
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
IOUtils.copy(zipInput, bos);
String xml = bos.toString();
assert xml.contains("A1");
assert xml.contains("B2");
assert xml.contains("C3");
break;
}