POI 正在读取 Excel 个正文为字符串的文件

POI reading Excel file with body in String

当前我正在尝试读取通过 Apache Camel (2.25.1) 轮询的 Excel 文件。 这意味着该方法通过字符串获取文件内容:

@Handler
public void processFile(@Body String body) {

为了读取 Excel 文件,我使用 Apache POI 和 POI-ooxml(均为 4.1.2)。

但是,直接使用字符串

WorkbookFactory.create(new ByteArrayInputStream(body.getBytes(Charset.forName("UTF-8"))))

抛出“java.io.IOException:ZIP 条目大小太大或无效”。

将字符串与其他编码一起使用:

WorkbookFactory.create(new ByteArrayInputStream(body.getBytes()))

抛出“org.apache.poi.openxml4j.exceptions.NotOfficeXmlFileException: 未找到有效的条目或内容,这不是有效的 OOXML (Office Open XML) 文件”。

此外,我试过:

File file = exchange.getIn().getBody(File.class);
Workbook workbook = new XSSFWorkbook(new FileInputStream(file));

可能是因为文件是从 FTP 服务器读取的,所以抛出 java.io.FileNotFoundException:文件路径无效

但是,下一个代码确实有效:

URL url = new URL(fileFtpPath);
URLConnection urlc = url.openConnection();
InputStream ftpIs = urlc.getInputStream();
Workbook workbook = new XSSFWorkbook(ftpIs);

但我不想自己连接到 FTP 服务器,因为 Camel 已经读取了文件并且所需的 Excel 内容可用(在字符串正文中)。 有什么方法可以使用 Apache POI 从字符串中读取 Excel 文件的内容吗?

我在 XML 中有我的路由,所以我使用 groovy 来处理 excel 个文件,也许你会发现它有用

import org.apache.poi.ss.usermodel.WorkbookFactory

def workbook = WorkbookFactory.create(request.getBody(File.class))
def sheet = workbook.getSheetAt(0)
...

还有另一种方法通常用于处理流的大型 excel 文件。要走这条路,我们应该从 org.apache.poi.xssf.eventusermodel
实现 XSSFSheetXMLHandler.SheetContentsHandler 您可以在此 , for some reason it was recently deleted from poi svn 中找到原始 POI 示例的副本。如果你有兴趣,我的groovy版本是这样的

import org.apache.poi.openxml4j.opc.OPCPackage
import org.apache.poi.ooxml.util.SAXHelper
import org.apache.poi.xssf.eventusermodel.XSSFReader
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable
import org.apache.poi.hssf.usermodel.HSSFDataFormatter
import org.xml.sax.InputSource

class MyHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
    ...
}

def pkg = OPCPackage.open(request.getBody(InputStream.class))
def xssfReader = new XSSFReader(pkg)
def sheetParser = SAXHelper.newXMLReader()

def handler = new XSSFSheetXMLHandler(xssfReader.getStylesTable(), null, new ReadOnlySharedStringsTable(pkg), MyHandler, new HSSFDataFormatter(), false)
sheetParser.setContentHandler(handler)
sheetParser.parse(new InputSource(xssfReader.getSheetsData().next()))