Android 使用 Poi 生成 World 文件
注意,查看了 poi-tl 的 release,它在 1.5.0 开始,升级了 poi 组件到 4.0.0,而 poishadow-all.jar 这个兼容Android的 jar 只支持到了 POI 3.17 ,所以如果导入 poi-tl 1.5.0 以上版本会有兼容问题,导致无法使用。如果确实需要使用 poi-tl ,建议使用 1.4.0 版本,例如我当初接入的时候使用的是 1.4.2
在 Android 平台中,如果直接导入并使用 poi 会直接无法编译
如果要使用原生的 poi,推荐看看这个 issues
作者编译了一个 poishadow-all.jar
库,直接导入这个 jar 就可以使用了
这是 作者仓库
但是我想使用 poi-tl
,因为它可以直接使用模板填充,完全满足我目前的工作需求。
Android 使用 poi-tl 填充生成 world 文件
如果直接按照官网的操作,使用 gradle 导入
compile group: 'com.deepoove', name: 'poi-tl', version: '1.4.2'
这样是无法编译的。解决方法
采用这样的方式导入,在 build.gradle
中
implementation('com.deepoove:poi-tl:1.4.2') {
//在Android 中 poi-tl 所依赖的库会导致无法编译
//所以只使用 poi-tl 的填充功能
//然后使用其他作者提供的 poi
//下面是过滤掉 poi-tl 的依赖库
exclude group: 'org.apache.xmlbeans', module: 'xmlbeans'
exclude group: 'org.apache.poi', module: 'poi-ooxml'
exclude group: 'org.apache.poi', module: 'poi-ooxml-schemas'
exclude group: 'org.apache.poi', module: 'poi'
}
主要是下面的 exclude
,把poi-tl
的依赖全部取消掉,然后到这个仓库下载可用的 jar
包
也可以 点击直接下载 jar 包
放入这个 jar 包到app工程的 libs 中,然后在 build.gradle 文件中
implementation files('libs/poishadow-all.jar')
至此已经添加好了依赖库,还有最后一步操作,执行下面的操作
(你可以在 onCreate 前,或者初始化的时候执行它,但必须保证是在使用 poi 前)
System.setProperty("org.apache.poi.javax.xml.stream.XMLInputFactory", "com.fasterxml.aalto.stax.InputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");
就可以了
其它使用方式就和 poi-tl 没有任何差别了
/**
* @param path 需要保存的world的路径
*/
fun generaWorld(path: String, map: HashMap<String, Any>?, mActivity: Context?) {
LogUtil.v(TAG, "save world to file,map:" + LogUtil.objToString(map))
System.setProperty("org.apache.poi.javax.xml.stream.XMLInputFactory", "com.fasterxml.aalto.stax.InputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLOutputFactory", "com.fasterxml.aalto.stax.OutputFactoryImpl");
System.setProperty("org.apache.poi.javax.xml.stream.XMLEventFactory", "com.fasterxml.aalto.stax.EventFactoryImpl");
val inputStream = mActivity?.assets?.open("model.docx")
if (inputStream == null) {
LogUtil.e("can not read template file,please check assets:model.docx")
Toast.show(mActivity?.getString(R.string.save_faild_cannot_read_file))
return
}
val template = XWPFTemplate.compile(inputStream)
map?.let {
template.render(map)
}
var outputStream: FileOutputStream? = null
try {
outputStream = FileUtil.instant.getFileOutputStream(path)
if (outputStream == null) {
LogUtil.w(TAG, "world path:$path is null,check permiss")
Toast.show(mActivity.getString(R.string.save_faild_cannot_writ))
return
}
template.write(outputStream)
outputStream.flush()
Toast.show("save success,path:$path")
} catch (e: IOException) {
LogUtil.e(TAG, "world write to output stream io exception:" +
LogUtil.objToString(e))
Toast.show(mActivity.getString(R.string.save_faild_cannot_writ))
} finally {
try {
template.close()
outputStream?.close()
} finally {
LogUtil.i(TAG, "write world to $path output stream over")
}
}
}