Java ApachePOI在读取文件而不是流时引发编码错误

Java ApachePOI在读取文件而不是流时引发编码错误,java,character-encoding,apache-poi,Java,Character Encoding,Apache Poi,当通过Java 7中的Apache POI 3.17加载特定的Excel XLSX文件时,我得到一个关于编码org.Apache.xerces.impl.io.MalformedByteSequenceException的异常:4字节UTF-8序列的无效字节2。这似乎是在读取sharedStrings.xml文件nb时出现的。该文件以UTF8编码 但是,如果我通过InputStream而不是文件加载该文件,则该文件将正确加载。在这两种情况下,我都不能指定编码。我知道从InputStream加载不

当通过Java 7中的Apache POI 3.17加载特定的Excel XLSX文件时,我得到一个关于编码org.Apache.xerces.impl.io.MalformedByteSequenceException的异常:4字节UTF-8序列的无效字节2。这似乎是在读取sharedStrings.xml文件nb时出现的。该文件以UTF8编码

但是,如果我通过InputStream而不是文件加载该文件,则该文件将正确加载。在这两种情况下,我都不能指定编码。我知道从InputStream加载不是最优的,我希望避免这种情况

我已经写了一个小例子来突出我的问题,但不幸的是,我无法共享有问题的文件:

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.MessageFormat;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;

public class POIEncodingIssue
{
    public static void main(final String[] args) throws Exception
    {
        final File file = new File("path\\to\\my\\file.xlsx"); //$NON-NLS-1$
        Workbook workbook = null;

        // This works
        System.out.println("Trying Stream based approach..."); //$NON-NLS-1$
        try (InputStream stream = new FileInputStream(file))
        {
            workbook = WorkbookFactory.create(stream);

            System.out.println(MessageFormat.format("Value was \"{0}\"", workbook.getSheetAt(0).getRow(0).getCell(0))); //$NON-NLS-1$
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (workbook != null)
            {
                workbook.close();
            }
        }

        // This doesn't
        System.out.println("Trying File based approach..."); //$NON-NLS-1$
        try
        {
            workbook = WorkbookFactory.create(file);

            System.out.println(MessageFormat.format("Value was \"{0}\"", workbook.getSheetAt(0).getRow(0).getCell(0))); //$NON-NLS-1$
        }
        catch (final Exception e)
        {
            e.printStackTrace();
        }
        finally
        {
            if (workbook != null)
            {
                workbook.close();
            }
        }
    }
}
以及产生的例外情况:

org.apache.poi.POIXMLException: java.lang.reflect.InvocationTargetException
    at org.apache.poi.POIXMLFactory.createDocumentPart(POIXMLFactory.java:63)
    at org.apache.poi.POIXMLDocumentPart.read(POIXMLDocumentPart.java:580)
    at org.apache.poi.POIXMLDocument.load(POIXMLDocument.java:165)
    at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:270)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:266)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:226)
    at org.apache.poi.ss.usermodel.WorkbookFactory.create(WorkbookFactory.java:205)
    at com.in2.excelreader_art.DAT3983Example.main(DAT3983Example.java:42)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
    at org.apache.poi.xssf.usermodel.XSSFFactory.createDocumentPart(XSSFFactory.java:56)
    at org.apache.poi.POIXMLFactory.createDocumentPart(POIXMLFactory.java:60)
    ... 7 more
Caused by: java.io.IOException: Unable to parse xml bean
    at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:166)
    at org.openxmlformats.schemas.spreadsheetml.x2006.main.SstDocument$Factory.parse(Unknown Source)
    at org.apache.poi.xssf.model.SharedStringsTable.readFrom(SharedStringsTable.java:119)
    at org.apache.poi.xssf.model.SharedStringsTable.<init>(SharedStringsTable.java:107)
    ... 13 more
Caused by: org.xml.sax.SAXParseException; lineNumber: 2; columnNumber: 5443012; Invalid byte 2 of 4-byte UTF-8 sequence.
    at org.apache.xerces.util.ErrorHandlerWrapper.createSAXParseException(Unknown Source)
    at org.apache.xerces.util.ErrorHandlerWrapper.fatalError(Unknown Source)
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    at org.apache.xerces.impl.XMLErrorReporter.reportError(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.DOMParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.DocumentBuilderImpl.parse(Unknown Source)
    at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:121)
    at org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:140)
    at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:163)
    ... 16 more
Caused by: org.apache.xerces.impl.io.MalformedByteSequenceException: Invalid byte 2 of 4-byte UTF-8 sequence.
    at org.apache.xerces.impl.io.UTF8Reader.invalidByte(Unknown Source)
    at org.apache.xerces.impl.io.UTF8Reader.read(Unknown Source)
    at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source)
    at org.apache.xerces.impl.XMLEntityScanner.scanContent(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanContent(Unknown Source)
    ... 26 more

将评论升级为答案

您似乎遇到了旧版本ApacheXMLBeans中的一个bug。如果升级到至少,您应该会发现问题消失了


理想情况下,您还应该至少升级到ApachePOI4.0.0,这需要更新的xmlbeans,但需要Java8+。xmlbeans是向后兼容的,因此您可以坚持POI3.17,只升级xmlbeans而不会出现问题,尽管显然没有POI4中的修复

您使用的是什么版本的Apache POI和Apache xmlbeans?@Gagravarr我已将此信息添加到问题中,抱歉。@Jakg将按照问题答案中的建议进行操作,并更改WorkbookFactory.createfile;到WorkbookFactory.createfile.getExcelFile;如果需要,还可以使用记事本将文件另存为UTF-8。@Jaybro90对不起,我不明白-我已经有一个Java.io.file文件,没有用于此的getExcelFile方法,也没有意义。sharedStrings.xml文件的编码已经是UTF-8,我不确定原始文件的编码,尽管它是一个ZIP容器,我不知道这有什么相关性。然而,即使它是不正确的,我也需要能够从我的应用程序中解决这个问题,而不是从其他方面。你能试试上周发布的ApachePOI4.0和2-3周前发布的ApacheXMLBeans 3.0.1,看看它是否已经解决了?