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

如何将Android XML布局转换为PDF?尝试现有教程效果不佳,希望通过截图实现

Android XML布局转PDF实现方案

现有代码问题

  • 重复声明Bitmap变量:方法内重新定义了和成员变量同名的bitmap,会导致取值逻辑异常
  • 缺失XML布局转Bitmap的核心步骤,没有实现XML布局截图逻辑
  • 未适配Android7.0及以上系统的文件访问规则,直接调用Uri.fromFile会触发FileUriExposedException崩溃
  • 存储路径合法性校验不全,未做权限获取判断逻辑

完整实现步骤

  1. 先对目标XML布局生成截图Bitmap
  2. 修正PDF生成逻辑,修复变量重复定义问题
  3. 适配高版本系统的PDF文件打开权限

可用实现代码

1. XML布局转Bitmap方法

// 针对已经渲染在当前页面的View生成截图
private Bitmap getBitmapFromView(View view) {
    Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}
// 针对未渲染的XML布局文件生成截图
private Bitmap getBitmapFromXml(int layoutId) {
    View view = LayoutInflater.from(this).inflate(layoutId, null);
    view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    view.draw(canvas);
    return bitmap;
}

2. 修正后的PDF生成方法

private void createPdf() {
    // 替换为你自己的目标XML布局ID,或者传入已经渲染的View对象获取Bitmap
    Bitmap bitmap = getBitmapFromXml(R.layout.your_target_layout);
    PdfDocument document = new PdfDocument();
    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), bitmap.getHeight(), 1).create();
    PdfDocument.Page page = document.startPage(pageInfo);

    Canvas canvas = page.getCanvas();
    Paint paint = new Paint();
    paint.setColor(Color.parseColor("#ffffff"));
    canvas.drawPaint(paint);

    canvas.drawBitmap(bitmap, 0, 0, paint);
    document.finishPage(page);
    
    // 默认存入公共下载目录,避免权限适配问题
    String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
    File file = new File(path);
    if (!file.exists()) {
        file.mkdirs();
    }
    String targetPdf = path + File.separator + "test-2.pdf";
    File filePath = new File(targetPdf);
    try {
        document.writeTo(new FileOutputStream(filePath));
        Toast.makeText(this, "PDF生成成功,存储路径:" + targetPdf, Toast.LENGTH_LONG).show();
        // 生成成功后直接打开PDF
        openPdf(targetPdf);
    } catch (IOException e) {
        Log.e("PDF生成", "错误信息: " + e.toString());
        Toast.makeText(this, "生成失败:" + e.toString(),  Toast.LENGTH_LONG).show();
    }
    document.close();
    bitmap.recycle(); // 及时回收Bitmap避免内存泄漏
}

3. 适配高版本系统的PDF打开方法

首先需要在AndroidManifest.xml中配置FileProvider适配文件访问:

<application>
    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="${applicationId}.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
    </provider>
</application>

在res/xml目录下新建file_paths.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path name="download" path="Download/" />
</paths>

修正后的openPdf方法:

private void openPdf(String path) {
    File file = new File(path);
    Intent target = new Intent(Intent.ACTION_VIEW);
    Uri uri;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        uri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", file);
        target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    } else {
        uri = Uri.fromFile(file);
    }
    target.setDataAndType(uri, "application/pdf");
    target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

    Intent intent = Intent.createChooser(target, "打开PDF文件");
    try{
        startActivity(intent);
    }catch (ActivityNotFoundException e){
        Toast.makeText(this, "没有安装可以打开PDF的应用", Toast.LENGTH_SHORT).show();
    }
}

注意事项

  • Android 12及以下版本需要动态申请WRITE_EXTERNAL_STORAGE权限,Android13及以上不需要额外存储权限即可写入公共下载目录
  • 如果布局尺寸过大,可以适当缩放Bitmap大小,降低PDF文件体积

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 03:18:02