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

Android中使用PdfDocument将LinearLayout转PDF并实现多页分页

Android LinearLayout 转自动分页PDF实现方案

你原有单页生成逻辑的核心问题是直接将LinearLayout的总高度作为单页PDF的高度,所有内容会被强制塞到同一页,超出页面范围的内容会直接丢失。要实现长内容自动分页,核心逻辑是按固定单页尺寸逐页裁切布局内容绘制,具体实现如下:

实现思路

  • 采用标准A4纸尺寸作为单页PDF的固定宽高,避免单页过长
  • 主动测量LinearLayout的完整内容高度(包含屏幕可视区域外的滚动内容)
  • 按单页高度计算总页数,逐页生成PDF
  • 绘制每一页时通过画布偏移,将布局对应位置的内容映射到当前页的可视区域,超出画布范围的内容会自动裁切,实现分页效果

完整实现代码

// 标准A4纸尺寸 72dpi下对应像素值,可根据需求调整
private static final int PDF_PAGE_WIDTH = 595;
private static final int PDF_PAGE_HEIGHT = 842;

private void generatePdfFromLinearLayout(LinearLayout linear2, File outputFile) {
    PdfDocument document = new PdfDocument();
    FileOutputStream fos = null;
    try {
        // 1. 测量布局完整尺寸,包含未在屏幕显示的内容
        int widthSpec = View.MeasureSpec.makeMeasureSpec(PDF_PAGE_WIDTH, View.MeasureSpec.EXACTLY);
        int heightSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
        linear2.measure(widthSpec, heightSpec);
        int totalContentHeight = linear2.getMeasuredHeight();
        // 对布局进行排版,确定所有子View的位置
        linear2.layout(0, 0, linear2.getMeasuredWidth(), totalContentHeight);

        // 2. 计算总页数
        int totalPages = (int) Math.ceil((double) totalContentHeight / PDF_PAGE_HEIGHT);

        // 3. 逐页生成PDF内容
        for (int pageIndex = 0; pageIndex < totalPages; pageIndex++) {
            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(
                    PDF_PAGE_WIDTH, 
                    PDF_PAGE_HEIGHT, 
                    pageIndex + 1
            ).create();
            PdfDocument.Page page = document.startPage(pageInfo);
            Canvas canvas = page.getCanvas();

            // 核心:向上偏移画布,将当前页对应位置的内容移动到画布可视区域
            canvas.translate(0f, -pageIndex * PDF_PAGE_HEIGHT);
            // 绘制布局,超出当前页画布的内容会自动被裁切
            linear2.draw(canvas);

            document.finishPage(page);
        }

        // 4. 将PDF写入文件
        fos = new FileOutputStream(outputFile);
        document.writeTo(fos);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 资源释放
        try {
            if (fos != null) fos.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        document.close();
    }
}

注意事项

  • 不要直接取LinearLayout在屏幕上显示的宽高生成PDF,屏幕上的布局可能被父容器裁切、或因滚动未完全展示,必须通过measure()和layout()方法重新测量排版,才能拿到完整的内容尺寸。
  • 如果布局内包含网络图片、异步加载的自定义View,要等所有内容加载完成后再调用PDF生成逻辑,避免出现内容空白。
  • 如果需要添加页边距,可在绘制前给Canvas额外增加对应边距的偏移,同时计算总页数时将单页高度减去上下页边距的总和即可。
  • PDF生成属于耗时操作,不要在主线程执行,建议放到子线程或协程中处理,避免阻塞UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 15:48:36