You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android实现长截图分割生成多页PDF解决方案求助

长截图分割为多页PDF的实现方案

问题描述

我有一个展示发票的布局,通过截取该布局的截图并转换为PDF文件。目前生成的PDF看似正常,但当发票列表项增多时,布局会被压缩以适配单页PDF。需要将长截图分割为两部分,分别放入PDF的不同页面中。

原代码问题

当前代码仅能将整张截图放入单页PDF,无法处理长截图的分页需求。

修改后的实现代码

1. 添加Bitmap分割工具方法

这个方法负责将长截图按高度分割为多个Bitmap(这里先实现分成两页的逻辑,可按需扩展):

private fun splitBitmap(originalBitmap: Bitmap): List<Bitmap> {
    val splitBitmaps = mutableListOf<Bitmap>()
    // 按高度平均分割为两页,可替换为固定页面高度(如A4纸像素高度)
    val singlePageHeight = originalBitmap.height / 2

    // 截取第一页内容:从顶部到分割线
    val firstPageBitmap = Bitmap.createBitmap(
        originalBitmap,
        0,
        0,
        originalBitmap.width,
        singlePageHeight
    )
    splitBitmaps.add(firstPageBitmap)

    // 截取第二页内容:从分割线到底部
    val secondPageBitmap = Bitmap.createBitmap(
        originalBitmap,
        0,
        singlePageHeight,
        originalBitmap.width,
        originalBitmap.height - singlePageHeight
    )
    splitBitmaps.add(secondPageBitmap)

    return splitBitmaps
}

2. 修改PDF生成方法

在generatePDF中调用分割方法,为每个分割后的Bitmap创建独立PDF页面:

private fun generatePDF() {
    Log.i(TAG + INVOICE_TEMPLATE1, "generatePDF")
    try {
        val pdfDocument = PdfDocument()
        // 分割长截图为多个页面Bitmap
        val pageBitmaps = splitBitmap(bitmap)

        pageBitmaps.forEachIndexed { pageIndex, pageBitmap ->
            // 创建对应页面的配置信息
            val pageInfo = PdfDocument.PageInfo.Builder(
                pageBitmap.width,
                pageBitmap.height,
                pageIndex + 1 // 页码从1开始
            ).create()
            // 启动页面并绘制Bitmap
            val page = pdfDocument.startPage(pageInfo)
            page.canvas.drawBitmap(pageBitmap, 0f, 0f, null)
            pdfDocument.finishPage(page)
            // 回收Bitmap释放内存
            pageBitmap.recycle()
        }

        // 保存PDF文件
        val directoryPath = this.getExternalFilesDir(null)!!.path + "/" + id + ".pdf"
        myFile = File(directoryPath)
        pdfDocument.writeTo(FileOutputStream(myFile))
        pdfDocument.close()
        // 回收原截图Bitmap
        bitmap.recycle()
        closeLoader()
    } catch (ex: Exception) {
        Log.e(TAG + INVOICE_TEMPLATE1, "generatePDF failed", ex)
    }
}

扩展说明

  • 如果需要支持超过两页的长截图,可以修改splitBitmap方法,通过循环按固定页面高度逐步截取,直到处理完整个原Bitmap。
  • 建议使用标准纸张尺寸的像素高度(如A4纸的像素高度,可根据屏幕密度计算)来替代平均分割,让PDF页面尺寸更规范。
  • 必须调用Bitmap.recycle()避免内存泄漏,尤其是处理大尺寸截图时。

内容的提问来源于stack exchange,提问作者user2357113

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:35:40