android 讀取excel xlsx 格式資料--未使用poi
修改以下例子:
https://code.google.com/archive/p/sjxslx/
https://github.com/davidpelfree/sjxlsx
因為我是使用在android上, 而以上兩個範例都是java的例子
執行時會一直出現com.bea.xml.stream.MXParserFactory找不到的錯誤
edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider om.bea.xml.stream.MXParserFactory not found
但這個class事實上存在 stax-1.2.0.jar 中, 無論在gradle中, 使用
compile file 或 provided file 的方法或直接加到 libs 都無法找到
此class, 我甚至把com.bea.xml.stream.MXParserFactory
直接抽出, 重新打包到stax-api-android-1.0-2.jar這個原來就存
在且可使用的 jar 裡也一樣找不到.
找到source code 想要改寫MXParserFactory但發現裡面又牽扯太廣太深,
不好改寫
修改 XMLInputFactory 成 MyXMLInputFactory, find函數,裡面
第二個參數 由com.bea.xml.stream.MXParserFactory 改成
edu.usf.cutr.javax.xml.stream.XMLEventFactory
如下:
MyFactoryFinder.find("edu.usf.cutr.javax.xml.stream.XMLInputFactory", "edu.usf.cutr.javax.xml.stream.XMLEventFactory");
錯誤訊息變成:
Provider edu.usf.cutr.javax.xml.stream.XMLEventFactory could not be instantiated:
可見已經找到了, 只是無法instantiated
可見只有com.bea.xml.stream 開頭的class找不到, 不知是否一樣要改成
edu.usf.cutr才可以
(見 http://save-coco.blogspot.tw/2016/05/javaxxmlstreamandroidlibraries.html)
另外在FactoryFinder中有使用到"META-INF/services/", 可能因為
android 不會把 META-INF 內的文件安裝到apk, 也會出問題
(update:確定不是此原因)
所以總之放棄此作法
https://pan.baidu.com/s/1o7HoY3w
update:20160605
經過幾天的努力, 終於可以成功讀取了.
provider com.bea.xml.stream.MXParserFactory 找不到的問題終於解決了
參考 http://stackoverflow.com/questions/30968735/using-com-bea-xml-stream-package-on-android
原文
I believe the main issue here is that Apache POI depends on JSR173
Streaming API for XML, which depends on the platform (in our case Android)
being able to provide an implementation and underlying XML parsing provider. Android doesn't support JSR173, so it can't find a provider - com.bea.xml.stream.EventFactory is the default provider, and it can't even find that one (see JAXB marshalling exception javax.xml.stream.FactoryConfigurationError running with Java 5 for more details on this topic).
Aalto is an open-source JSR173 provider, so you should be able to use this in place of the BEA implementation (com.bea.xml.stream.EventFactory). The Aalto archive (JAR file) includes the necessary registration (under META-INF/services/javax.xml.stream.XMLInputFactory file, that points to the Aalto class com.fasterxml.aalto.stax.InputFactoryImpl) that should allow a Java platform to recognize it as a JSR173 implementation. As a result, you should no longer get the edu.usf.cutr.javax.xml.stream.FactoryConfigurationError: Provider com.bea.xml.stream.EventFactory not found error, because Android should recognize that Aalto is an available provider, and use Aalto instead.
大意是說:Apache POI 必須依賴JSR173 Streaming API for XML 作為
provider , 但 android 不支援 JSR173 , 所以才會出現找不到作為 provider的 com.bea.xml.stream.EventFactory .而必須改用Aalto , 而且
android 支援 Aalto .
所以在android想要讀取xlsx資料, 必須更改使用的provider, 將
stax-api中stax-api-1.0-2.jar 換成Aalto 的 aalto-xml-android-0.9.8.jar
Aalto有幾個不同的 class
com.fasterxml.aalto.stax.EventFactoryImpl
com.fasterxml.aalto.stax.InputFactoryImpl
com.fasterxml.aalto.stax.OutputFactoryImpl
必須查看原程式碼傳回那一個物件來決定採用那個 provider
所以要在android 讀 excel 的重點就是
1.必須修改原始碼, 更改 provider
2.還有必須將 javax.xml.stream 更名
修改原始碼, 更改 provider 舉例如下:
修改 aavax.xml.stream.XMLEventFactory 的原始碼
(aavax是javax更名而來的,見:將 javax.xml.stream 更名)
(找 stax-api-fix-1.0-2.jar 的source來改)
把原來的 com.bea.xml.stream.EventFactory 改成
com.fasterxml.aalto.stax.EventFactoryImpl
(不是 com.fasterxml.aalto.stax.InputFactoryImpl, 因為原程式碼必須傳
回 XMLEventFactory 而不是 XMLInputFactory , 使用 XMLInputFactory 會出
現型別轉換錯誤)
//注意1: XMLEventFactory 配合 EventFactoryImpl
public static XMLEventFactory newInstance() throws FactoryConfigurationError {
//原來的 source
// return (XMLEventFactory)FactoryFinder.find
//("aavax.xml.stream.XMLEventFactory", "com.bea.xml.stream.EventFactory");
//改成這樣
return (XMLEventFactory)FactoryFinder.find
("aavax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");
}
再將source 重新compile , 重新打包
修改 class 重新打包, 請參考:
http://save-coco.blogspot.tw/2016/06/java-android-jar-class.html
將 javax.xml.stream 更名 請參考
http://save-coco.blogspot.tw/2016/06/jar-class.html
完成的專案