Android免费实现excel文件(简单)转为PDF文件

文章目录

前言:
在Android中,对于excel文件无法进行直接展示,只能通过其他方式进行间接展示,免费的相对来说比较复杂,如果只是个人使用的话或者可支持付费商用使用的话,推荐使用 Aspose.Cells进行实现,如果是简单的表格可以使用 POI+itext 的形式进行实现

1、POI依赖

导入完整的POI库的依赖:

kotlin 复制代码
implementation 'org.apache.poi:poi:5.2.3'
implementation 'org.apache.poi:poi-ooxml:5.2.3'

POI库中数据过于多,所以我用的是简化版的

下载 android5xlsx 项目中两个jar包放在自己文件的libs路径下,比添加依赖

kotlin 复制代码
 implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar', '*.so'])

2、iText的依赖

kotlin 复制代码
implementation "com.itextpdf:itextpdf:5.5.13"

字体大合集

3、将excel文件转为PDF文件

3.1 判断是否为xls和xlsx文件

kotlin 复制代码
 /**
     * 根据类型后缀名简单判断是否Excel文件
     * @param file 文件
     * @return 是否Excel文件
     */
    private fun checkIfExcelFile(file: File?): Boolean {
        if (file == null) {
            return false
        }
        val name = file.name
        //"." 需要转义字符
        val list = name.split("\\.".toRegex()).dropLastWhile { it.isEmpty() }
            .toTypedArray()
        //划分后的小于2个元素说明不可获取类型名
        if (list.size < 2) {
            return false
        }
        val typeName = list[list.size - 1]
        //满足xls或者xlsx才可以
        return "xls" == typeName || "xlsx" == typeName

    }

3.2 将excel文件转为pdf文件

将excel文件中的单元格中字符进行循环遍历,写入到生成的pdf文件中,并对其展示效果进行处理。

kotlin 复制代码
 /**
     * 将excel文件转为Pdf文件
     * @param excelName 文件名称(带文件后缀)
     * @param path 文件存放路径
     * @param pdfName 转换后的文件名称
     */
    fun convertExcelToPdf(context: Context, excelName: String, path: String, pdfName: String) {

        if (!checkIfExcelFile(File("$path/$excelName"))) return

        var document: Document? = null
        var  writer: PdfWriter? = null
        var workbook: Workbook? = null
        var fontStream: InputStream? = null
        val pdfFile = File(path, pdfName)
        try {
            // ==================== 1. 文件路径有效性校验 ====================
            val excelFile = File("$path/$excelName")


            if (!excelFile.exists()) {
                throw FileNotFoundException("Excel文件不存在: ${excelFile.absolutePath}")
            }

            // ==================== 2. 安全初始化PDF文档 ====================
            document = Document(PageSize.A4.rotate()) // 改用A4横向以适应表格
             writer = PdfWriter.getInstance(document, FileOutputStream(pdfFile))
            document.open()

            // ==================== 3. 字体加载优化 ====================
            fontStream = try {
                context.assets.open("fonts/$ttfName")
            } catch (e: Exception) {
                throw IOException("字体文件加载失败: ${e.message}")
            }

            val fontBytes = fontStream.use { it?.readBytes() }

            val chineseFont = BaseFont.createFont(
                ttfName, // 必须包含文件后缀
                BaseFont.IDENTITY_H,
                BaseFont.EMBEDDED,
                true,
                fontBytes,
                null
            )

            // ==================== 4. 表格样式优化 ====================
            workbook = WorkbookFactory.create(excelFile)
            val sheet = workbook.getSheetAt(0)

            // 添加标题(带错误处理)
            val titleFont = Font(chineseFont, 14f, Font.BOLD)
            val title = Paragraph(sheet.sheetName, titleFont).apply {
                alignment = Element.ALIGN_CENTER
                spacingAfter = 20f // 添加标题与表格间距
            }
            document.add(title)

            // 动态计算列宽(首行作为表头)
            val headerRow = sheet.getRow(0)
            val columnWidths = FloatArray(headerRow.lastCellNum.toInt()) { 1f }
            val table = PdfPTable(columnWidths).apply {
                headerRows = 1
                widthPercentage = 100f
                setWidths(columnWidths)
            }

            // ==================== 5. 数据填充优化 ====================
            for (row in sheet) {
                for (cell in row) {
                    val cellContent = getCellValue(cell)
                    val cellFont = if (cell.rowIndex == 0) {
                        Font(chineseFont, 12f, Font.BOLD, BaseColor.WHITE)
                    } else {
                        Font(chineseFont, 10f)
                    }

                    PdfPCell(Phrase(cellContent, cellFont)).apply {
                        borderWidth = 0.1f
                        borderColor = BaseColor.DARK_GRAY
                        paddingRight = 15f
                        paddingTop = 15f
                        paddingLeft = 15f
                        paddingBottom = 15f
                        horizontalAlignment = Element.ALIGN_CENTER
                        verticalAlignment = Element.ALIGN_MIDDLE
                        if (cell.rowIndex == 0) {
                            backgroundColor = BaseColor(79, 129, 189) // 专业蓝色表头
                        }
                    }.also { table.addCell(it) }
                }
            }

            // ==================== 6. 强制刷新缓冲区 ====================
            document.add(table)
            document.close()
            document = null // 防止重复关闭

            // 验证PDF文件生成结果
            if (!pdfFile.exists() || pdfFile.length() == 0L) {
                throw IOException("PDF文件生成失败")
            }
        } catch (e: Exception) {
            // ==================== 7. 增强错误处理 ====================
            Log.e("PDF生成", "错误信息: ${e.message}", e)

            pdfFile.delete() // 删除无效文件
            throw e
        } finally {
            // ==================== 8. 安全释放资源 ====================

          val resourseList =   mutableListOf(  document to { document?.close() },
              writer to { writer?.close() },
              workbook to { workbook?.close() },
              fontStream to { fontStream?.close() })
          resourseList.forEach { (resource, closer) ->
                try {
                    closer
                } catch (e: Exception) {
                    Log.w("ResourceClose", "资源释放失败", e)
                }
            }
        }
    }

    /**
     *  辅助函数:获取单元格值(处理空单元格)
     *
     */
    private fun getCellValue(cell: Cell): String {
        Logd.t("获取单元格中的数值 ${cell}")
        return when {
            cell.cellType == Cell.CELL_TYPE_STRING -> cell.stringCellValue
            cell.cellType == Cell.CELL_TYPE_NUMERIC -> DataFormatter().formatCellValue(cell)
            else -> cell.toString()
        }
    }

尾声

上述方法只能用于简单的表格转换,对于复杂的表格转换会出现格式错乱的效果

相关推荐
还鮟8 分钟前
CTF Web的数组巧用
android
小蜜蜂嗡嗡1 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi002 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
不坑老师3 小时前
利用不坑盒子的Copilot,快速排值班表
microsoft·word·powerpoint·excel·copilot·wps
zhangphil3 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你3 小时前
Android View的绘制原理详解
android
移动开发者1号6 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
开开心心就好6 小时前
批量PDF转换工具,一键转换Word Excel
开发语言·前端·学习·pdf·电脑·word·excel
移动开发者1号6 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best11 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android