当前位置: 首页 > 面试题库 >

读取XLSB文件Apache POI的异常java.io.CharConversionException

尉迟彬
2023-03-14
问题内容

我正在开发一种使用Apache POI读取excel xlsb文件的Java应用程序,但是在读取时出现异常,我的代码如下:

import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.Package;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;

import java.util.Iterator;

public class Prueba {

    public static void main (String [] args){

        String direccion = "C:/Documents and Settings/RSalasL/My Documents/New Folder/masstigeoct12.xlsb";

        Package pkg;
        try {
            pkg = Package.open(direccion);
            XSSFReader r = new XSSFReader(pkg);
            SharedStringsTable sst = r.getSharedStringsTable();

            XMLReader parser = fetchSheetParser(sst);

            Iterator<InputStream> sheets = r.getSheetsData();
            while(sheets.hasNext()) {
                System.out.println("Processing new sheet:\n");
                InputStream sheet = sheets.next();
                InputSource sheetSource = new InputSource(sheet);
                parser.parse(sheetSource);
                sheet.close();
                System.out.println("");
            }

        } catch (InvalidFormatException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (OpenXML4JException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void processAllSheets(String filename) throws Exception {
        Package pkg = Package.open(filename);
        XSSFReader r = new XSSFReader( pkg );
        SharedStringsTable sst = r.getSharedStringsTable();

        XMLReader parser = fetchSheetParser(sst);

        Iterator<InputStream> sheets = r.getSheetsData();
        while(sheets.hasNext()) {
            System.out.println("Processing new sheet:\n");
            InputStream sheet = sheets.next();
            InputSource sheetSource = new InputSource(sheet);
            parser.parse(sheetSource);
            sheet.close();
            System.out.println("");
        }
    }


    public static XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
        XMLReader parser =
            XMLReaderFactory.createXMLReader(
                    "org.apache.xerces.parsers.SAXParser"
            );
        ContentHandler handler = new SheetHandler(sst);
        parser.setContentHandler(handler);
        return parser;
    }

    private static class SheetHandler extends DefaultHandler {
        private SharedStringsTable sst;
        private String lastContents;
        private boolean nextIsString;

        private SheetHandler(SharedStringsTable sst) {
            this.sst = sst;
        }

        public void startElement(String uri, String localName, String name,
                Attributes attributes) throws SAXException {
            // c => cell
            if(name.equals("c")) {
                // Print the cell reference
                System.out.print(attributes.getValue("r") + " - ");
                // Figure out if the value is an index in the SST
                String cellType = attributes.getValue("t");
                if(cellType != null && cellType.equals("s")) {
                    nextIsString = true;
                } else {
                    nextIsString = false;
                }
            }
            // Clear contents cache
            lastContents = "";
        }

        public void endElement(String uri, String localName, String name)
                throws SAXException {
            // Process the last contents as required.
            // Do now, as characters() may be called more than once
            if(nextIsString) {
                int idx = Integer.parseInt(lastContents);
                lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
            nextIsString = false;
            }

            // v => contents of a cell
            // Output after we've seen the string contents
            if(name.equals("v")) {
                System.out.println(lastContents);
            }
        }

        public void characters(char[] ch, int start, int length)
                throws SAXException {
            lastContents += new String(ch, start, length);
        }
    }

}

唯一的例外是:

java.io.CharConversionException: Characters larger than 4 bytes are not supported: byte 0x83 implies a length of more than 4 bytes
    at org.apache.xmlbeans.impl.piccolo.xml.UTF8XMLDecoder.decode(UTF8XMLDecoder.java:162)
    at org.apache.xmlbeans.impl.piccolo.xml.XMLStreamReader$FastStreamDecoder.read(XMLStreamReader.java:762)
    at org.apache.xmlbeans.impl.piccolo.xml.XMLStreamReader.read(XMLStreamReader.java:162)
    at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yy_refill(PiccoloLexer.java:3474)
    at org.apache.xmlbeans.impl.piccolo.xml.PiccoloLexer.yylex(PiccoloLexer.java:3958)
    at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yylex(Piccolo.java:1290)
    at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.yyparse(Piccolo.java:1400)
    at org.apache.xmlbeans.impl.piccolo.xml.Piccolo.parse(Piccolo.java:714)
    at org.apache.xmlbeans.impl.store.Locale$SaxLoader.load(Locale.java:3439)
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1270)
    at org.apache.xmlbeans.impl.store.Locale.parseToXmlObject(Locale.java:1257)
    at org.apache.xmlbeans.impl.schema.SchemaTypeLoaderBase.parse(SchemaTypeLoaderBase.java:345)
    at org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument$Factory.parse(Unknown Source)
    at org.apache.poi.xssf.eventusermodel.XSSFReader$SheetIterator.<init>(XSSFReader.java:207)
    at org.apache.poi.xssf.eventusermodel.XSSFReader$SheetIterator.<init>(XSSFReader.java:166)
    at org.apache.poi.xssf.eventusermodel.XSSFReader.getSheetsData(XSSFReader.java:160)
    at EDManager.Prueba.main(Prueba.java:36)

该文件有2个工作表,一个有329行3列,另一个有566行3列,我只想读取文件以查找第二个表中是否有值。


问题答案:

除文本提取外,Apache POI不支持.xlsb文件格式。Apache
POI将很乐意提供对.xls文件(通过HSSF)和.xlsx文件(通过XSSF)或两者(通过公共SS UserModel接口)的完全读写支持。

但是,生成操作不支持.xlsb格式-这是两者之间非常奇怪的混合,并且涉及大量工作,这意味着没有人愿意自愿/赞助所需的工作。

从Apache POI 3.15 beta3 / 3.16开始,Apache
POI为.xlsb提供的功能是.xlsb文件的文本提取器-
XSSFBEventBasedExcelExtractor
。您可以使用它来从文件中提取文本,或进行一些调整将其转换为CSV之类的内容

为了获得完整的读/写支持,您需要将文件转换为.xls(如果它没有太多的行/列)或.xlsx(如果有)。如果您确实真的很想提供帮助,可以查看XSSFBEventBasedExcelExtractor的源代码,然后尝试提供补丁以为其提供对POI的全面支持!

(此外,我认为例外情况是您的特定.xlsb文件已部分损坏,但是即使不是它,Apache POI也不支持除文本提取以外的任何功能,对不起)



 类似资料:
  • 我已经提到了与使用ApachePOI读取XLSB文件相关的所有post-in堆栈溢出。我尝试了很多方法,使用本文中提到的可用链接/示例来读取XLSB文件。但我最终陷入了困境。 我使用的是最新的ApachePOI3.17,并使用了中提到的代码 链接:异常读取XLSB文件Apache POIjava.io.CharConversionExcture 章节:“Gagravarr”提到的帖子 我得到以下错

  • 问题内容: 对此有很多问题,但是对于如何将xlsb文件读入熊猫还没有简单的答案。是否有捷径可寻? 问题答案: 随着pandas-的发布,增加了对二进制Excel文件的支持。 笔记: 您将需要升级熊猫- 您将需要安装-

  • 所以我使用了DataInputStream、FileInputStream、BufferInputStream、FileReader、BufferedReader、Scanner。它们都抛出FileNOtFoundException或CorruptedStreamException。

  • 我正在尝试制作一个十六进制转储应用程序,为此,我需要读取文件字节。我正在使用ApacheIO版本2.8.0来进行十六进制转储。这是我正在使用的代码: 我得到的错误是:我查了一下,没有任何建议尝试如添加和到清单工作。任何帮助都很感激

  • 问题内容: 尝试使用ApachePOI打开Excel时,我得到 我检查了。没有创建这样的文件夹。我正在使用Apache POI 3.6版。 有什么帮助吗?类似的代码在其他工作区中运行良好。在这里不知所措。 码: 问题答案: 您为什么要制作一个非常好的文件,将其包装在中,然后要求POI必须为您缓冲整个文件,以便可以进行随机访问?如果直接将文件直接传递给POI,生活会好很多,因此可以根据需要跳过它!

  • 问题内容: 我正在使用Java在Linux EXTREME VPS上存储图像 当我将其存储在服务器路径上时 使用以下代码读取路径 当我使用上面的代码阅读时,我得到以下异常 如何解决这个问题呢? 还有其他从Linux服务器读取文件的方法吗? 问题答案: 我认为问题在于您使用的文件路径错误。 您说您正在Linux服务器上读取文件,似乎您正在尝试在Windows计算机上读取文件。由此推断,您已将Linu