Android 本地预览Excel,Word,PPT,PDF
解决Android asposed转Excel乱码问题
近期获得一个需求, 要求做一个类似WPS的功能, 不过只需要预览不需要编辑
Android本身没有提供预览Office的组件, 百度后发现腾讯TBS可以做到这一点,试了下,效果不尽人意;
- 附腾讯TBS链接 : https://x5.tencent.com/tbs/index.html
我采用的方案是首先通过aspose将excel,word,ppt转为pdf, 然后用PdfViewer打开;
-
aspose链接 : https://www.aspose.com/
-
PdfViewer链接 : https://github.com/barteksc/AndroidPdfViewer
-
需要引入cells , slides ,words 三个Jar包, 分别对应 Excel , PPT , Word ;
Jar包连带源码都下最后附上链接, jar包也可以直接用aspose官网下载;
运行效果实例
部分代码实例 :
选择文件【调用系统的文件管理】
/**
* 选择文件【调用系统的文件管理】
*/
private fun chooseFile() {
startActivityForResult(Intent().apply {
action = Intent.ACTION_GET_CONTENT
type = "*/*"
addCategory(Intent.CATEGORY_OPENABLE)
}, REQUEST_CHOOSE_FILE)
}
onActivityResult
// 选择文件返回
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == RESULT_OK) {
if (requestCode == REQUEST_CHOOSE_FILE) {
data?.let {
val uri = it.data
val path = FileChooseUtil.getInstance(this).getChooseFileResultPath(uri)
openFile(path)
}
}
}
}
openFile
private fun openFile(path: String) {
loading.visibility = View.VISIBLE
GlobalScope.launch {
val realPath = getRealPath(path)
runOnUiThread {
loading.visibility = View.INVISIBLE
if (TextUtils.isEmpty(realPath)) {
ToastUtils.showShort("格式不支持")
return@runOnUiThread
}
pdfView.fromFile(File(realPath))
.pages(0, 2, 1, 3, 3, 3) // all pages are displayed by default
.enableSwipe(true) // allows to block changing pages using swipe
.swipeHorizontal(false)
.enableDoubletap(true)
.defaultPage(0)
.onError {
ToastUtils.showLong("onError: ${it.message} ")
}
.onTap { false }
.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms)
.password(null)
.scrollHandle(null)
.enableAntialiasing(true) // improve rendering a little bit on low-res screens
// spacing between pages in dp. To define spacing color, set view background
.spacing(0)
.autoSpacing(false) // add dynamic spacing to fit each page on its own on the screen
.linkHandler {}
.pageFitPolicy(FitPolicy.WIDTH) // mode to fit pages in the view
.fitEachPage(false) // fit each page to the view, else smaller pages are scaled relative to largest page.
.pageSnap(false) // snap pages to screen boundaries
.pageFling(false) // make a fling change only a single page like ViewPager
.nightMode(false) // toggle night mode
.load()
}
}
}
getRealPath
/**
* 获取PDF路径
*/
private fun getRealPath(path: String): String {
// 首先需要判断 原始类型是否为PDF
val type = getFileType(path)
val fileName = getFileName(path)
// 如果是PDF 直接返回
if (type == "pdf") {
return path
}
val realPath = tempDir + File.separator + fileName + type + ".pdf"
// 如果已存在 直接返回
if (File(realPath).exists()) {
return realPath
}
// Word
if (type == "doc" || type == "docx") {
try {
val document = Document(path)
document.save(realPath, SaveFormat.PDF)
return realPath
} catch (e: Exception) {
e.printStackTrace()
}
// Excel
} else if (type == "xlsx" || type == "xls") {
try {
AsposedUtils.excel2pdf(path, realPath)
return realPath
} catch (e: Exception) {
e.printStackTrace()
}
// PPT
} else if (type == "ppt" || type == "pptx") {
try {
AsposedUtils.ppt2pdf(path, realPath)
return realPath
} catch (e: Exception) {
e.printStackTrace()
}
}
return ""
}
解决aspose excel转换后中文乱码问题
- 复制中文字体[随便选一个, 我选的微软雅黑]到assets中
- 将assets中的字体拷贝到储存中
- 转换Excel时, 将字体传给Workbook
- tempDir 下有微软雅黑字体
fun excel2pdf(sourceFilePath: String, desFilePath: String) {
try {
// 中文乱码处理 主要是设置微软雅黑字体
val configs = IndividualFontConfigs()
configs.setFontFolder(tempDir, true)
val loadOptions = LoadOptions()
loadOptions.fontConfigs = configs
// loadOptions.languageCode = CountryCode.CHINA
val pdfSaveOptions = PdfSaveOptions()
pdfSaveOptions.onePagePerSheet = true
// 原始excel路径
val wb = Workbook(sourceFilePath, loadOptions)
val fileOS = FileOutputStream(desFilePath)
// 数组为几就展示几页
val showSheets = intArrayOf(wb.worksheets.count)
// 隐藏workbook中不需要的sheet页。
// printSheetPage(wb, showSheets)
wb.save(fileOS, pdfSaveOptions)
fileOS.flush()
fileOS.close()
println("完毕")
} catch (e: Exception) {
e.printStackTrace()
}
}