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

如何从RecyclerView或Bitmap生成PDF?求新版解决方案

从RecyclerView生成PDF的现代解决方案

首先先优化你提供的RecyclerView截图函数,修复一处冗余的Canvas创建问题:

private fun getRecyclerViewScreenshotAsBitmap(
    recyclerView: RecyclerView,
    defaultColor: Int = Color.WHITE
): Bitmap {
    recyclerView.measure(
        View.MeasureSpec.makeMeasureSpec(recyclerView.width, View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    )

    val bitmap = Bitmap.createBitmap(
        recyclerView.width,
        recyclerView.measuredHeight,
        Bitmap.Config.ARGB_8888
    )
    val canvas = Canvas(bitmap)
    canvas.drawColor(defaultColor)
    // 复用已创建的Canvas,避免重复实例化
    recyclerView.draw(canvas)

    return bitmap
}

方案一:直接将RecyclerView内容绘制到PDF(无需先转Bitmap)

使用Android系统原生的PdfDocument类(属于AndroidX,无需额外依赖),直接将RecyclerView渲染到PDF页面,效率更高:

private fun generatePdfFromRecyclerView(recyclerView: RecyclerView, outputFile: File) {
    // 先测量RecyclerView总高度
    recyclerView.measure(
        View.MeasureSpec.makeMeasureSpec(recyclerView.width, View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
    )
    val rvWidth = recyclerView.measuredWidth
    val rvHeight = recyclerView.measuredHeight

    // 获取屏幕密度,用于将px转换为PDF的点单位(1pt = 1/72英寸)
    val displayMetrics = recyclerView.context.resources.displayMetrics
    val scale = displayMetrics.densityDpi / 72f

    // 创建PDF文档
    val pdfDocument = PdfDocument()
    // 创建PDF页面,尺寸对应RecyclerView的实际大小(转换为点)
    val pageInfo = PdfDocument.PageInfo.Builder(
        (rvWidth / scale).toInt(),
        (rvHeight / scale).toInt(),
        1
    ).create()
    // 获取页面画布
    val page = pdfDocument.startPage(pageInfo)
    val canvas = page.canvas

    // 缩放画布,适配PDF的点单位
    canvas.scale(1/scale, 1/scale)
    // 绘制背景色
    canvas.drawColor(Color.WHITE)
    // 将RecyclerView绘制到PDF画布
    recyclerView.draw(canvas)

    // 结束页面并保存PDF
    pdfDocument.finishPage(page)
    try {
        pdfDocument.writeTo(FileOutputStream(outputFile))
    } catch (e: IOException) {
        e.printStackTrace()
    } finally {
        pdfDocument.close()
    }
}

方案二:将已生成的Bitmap转换为PDF

如果已经通过你的截图函数得到了Bitmap,可直接将Bitmap绘制到PDF页面:

private fun generatePdfFromBitmap(bitmap: Bitmap, outputFile: File) {
    val displayMetrics = Resources.getSystem().displayMetrics
    val scale = displayMetrics.densityDpi / 72f

    val pdfDocument = PdfDocument()
    val pageInfo = PdfDocument.PageInfo.Builder(
        (bitmap.width / scale).toInt(),
        (bitmap.height / scale).toInt(),
        1
    ).create()
    val page = pdfDocument.startPage(pageInfo)
    val canvas = page.canvas

    // 缩放画布并绘制Bitmap
    canvas.scale(1/scale, 1/scale)
    canvas.drawBitmap(bitmap, 0f, 0f, null)

    pdfDocument.finishPage(page)
    try {
        pdfDocument.writeTo(FileOutputStream(outputFile))
    } catch (e: IOException) {
        e.printStackTrace()
    } finally {
        pdfDocument.close()
    }
}

注意事项

  • 权限处理:Android 10及以下需要申请WRITE_EXTERNAL_STORAGE权限;Android 11+推荐使用**存储访问框架(SAF)**让用户选择保存位置,避免权限问题。
  • 长列表处理:如果RecyclerView内容超过单页PDF大小,需要拆分内容到多个页面,可通过计算每页高度、滚动RecyclerView分段绘制实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 04:40:53