Android中用chaquopy调用docx2pdf转格式致应用崩溃求助
Android中Chaquopy结合docx2pdf崩溃的解决方案
崩溃的核心原因很明确:docx2pdf库的设计依赖Microsoft Word程序,而Android基于Linux内核,没有Word的运行环境,所以直接抛出NotImplementedError导致应用崩溃。必须更换不依赖桌面办公软件的转换方案。
方案一:使用纯Python跨平台转换库(适配Chaquopy)
选择不依赖外部办公软件的Python库,比如用python-docx读取docx内容,再用fpdf2生成PDF(这两个库都能在Chaquopy中正常运行)。
- 首先在app模块的
build.gradle中添加依赖:
chaquopy { pip { install "python-docx" install "fpdf2" } }
- 修改Python模块
MyModule.py:
from docx import Document from fpdf import FPDF def convertDocxToPdf(input_path, output_path): doc = Document(input_path) pdf = FPDF() pdf.add_page() pdf.set_font("Arial", size=12) # 遍历docx中的段落并写入PDF for para in doc.paragraphs: pdf.cell(200, 10, txt=para.text, ln=True, align='L') # 处理表格(可选) for table in doc.tables: for row in table.rows: row_text = " | ".join([cell.text for cell in row.cells]) pdf.cell(200, 10, txt=row_text, ln=True, align='L') pdf.output(output_path)
- Kotlin代码中添加异常捕获:
val py = Python.getInstance() val myModule = py.getModule("MyModule") try { myModule.callAttr("convertDocxToPdf", inputFile.absolutePath, outputFile.absolutePath) // 转换成功后的操作 } catch (e: PyException) { e.printStackTrace() // 处理转换失败的情况,比如提示用户 }
方案二:使用Android原生Java/Kotlin库(更稳定)
直接用Android原生的办公文档处理库,避免Python层的依赖问题,推荐组合:
- Apache POI:读取和解析docx文件
- iText 7:生成PDF文件
- 添加Gradle依赖:
implementation 'org.apache.poi:poi-ooxml:5.2.5' implementation 'com.itextpdf:itext7-core:7.2.5'
- Kotlin实现转换逻辑:
import org.apache.poi.xwpf.usermodel.XWPFDocument import com.itextpdf.kernel.pdf.PdfWriter import com.itextpdf.layout.Document import com.itextpdf.layout.element.Paragraph import com.itextpdf.layout.element.Table import java.io.FileInputStream fun convertDocxToPdf(inputPath: String, outputPath: String) { val doc = XWPFDocument(FileInputStream(inputPath)) val pdfWriter = PdfWriter(outputPath) val pdfDoc = com.itextpdf.kernel.pdf.PdfDocument(pdfWriter) val layoutDoc = Document(pdfDoc) // 处理段落 doc.paragraphs.forEach { para -> layoutDoc.add(Paragraph(para.text)) } // 处理表格(可选) doc.tables.forEach { table -> val pdfTable = Table(table.numberOfColumns.toFloat()) table.rows.forEach { row -> row.tableCells.forEach { cell -> pdfTable.addCell(cell.text) } } layoutDoc.add(pdfTable) } layoutDoc.close() pdfDoc.close() doc.close() }
调用时同样添加异常捕获:
try { convertDocxToPdf(inputFile.absolutePath, outputFile.absolutePath) } catch (e: Exception) { e.printStackTrace() // 提示转换失败 }
注意事项
- 两种方案都只处理了基础的文本和表格,复杂格式(比如图片、样式、页眉页脚)需要额外适配
- 对于大文件转换,建议放在后台线程(比如Coroutine的IO线程)执行,避免阻塞主线程
内容的提问来源于stack exchange,提问作者Atul Sharma
相关产品推荐
相关产品推荐

