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

Android Studio中如何打印RecyclerView数据的PDF文档

在Android中将RecyclerView的SQLite数据生成并打印PDF

1. 添加PDF生成依赖

在app/build.gradle(Module级别)的dependencies块中加入iText 7的依赖,用于PDF文档的创建:

implementation 'com.itextpdf:itext7-core:7.2.7'
implementation 'com.itextpdf:itext7-layout:7.2.7'

同步项目完成依赖导入。

2. 从SQLite获取数据集

假设你已有数据模型类(如Item)和数据库操作类(DBHelper),先获取RecyclerView对应的全量数据:

DBHelper dbHelper = new DBHelper(this);
List<Item> itemList = dbHelper.getAllItems(); // 替换为你的实际查询方法

3. 生成包含数据的PDF文件

编写方法将数据写入PDF,保存到设备内部存储的文档目录:

private File generatePDF(List<Item> itemList) throws IOException {
    // 创建PDF文件对象
    File pdfDir = getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
    File pdfFile = new File(pdfDir, "recycler_data.pdf");

    // 初始化PDF写入器和文档
    PdfWriter writer = new PdfWriter(pdfFile);
    PdfDocument pdfDoc = new PdfDocument(writer);
    Document document = new Document(pdfDoc);

    // 添加文档标题
    document.add(new Paragraph("RecyclerView 数据").setFontSize(18).setBold().setTextAlignment(TextAlignment.CENTER));
    document.add(new Paragraph("\n"));

    // 创建表格(假设每个Item有ID、名称、描述三个字段)
    Table table = new Table(3);
    // 添加表头
    table.addHeaderCell(new Cell().add(new Paragraph("ID").setBold()));
    table.addHeaderCell(new Cell().add(new Paragraph("名称").setBold()));
    table.addHeaderCell(new Cell().add(new Paragraph("描述").setBold()));

    // 遍历数据填充表格
    for (Item item : itemList) {
        table.addCell(new Cell().add(new Paragraph(String.valueOf(item.getId()))));
        table.addCell(new Cell().add(new Paragraph(item.getName())));
        table.addCell(new Cell().add(new Paragraph(item.getDescription())));
    }

    document.add(table);
    document.close();
    return pdfFile;
}

注意:需处理存储权限,Android 13+需申请READ_MEDIA_IMAGES(若需读取共享目录),低于13需申请WRITE_EXTERNAL_STORAGE,并在运行时动态请求。

4. 实现PDF打印功能

使用Android系统的PrintManager完成打印,需自定义打印适配器:

private void printPDF(File pdfFile) {
    PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
    String printJobName = getString(R.string.app_name) + " 数据打印";

    PdfDocumentAdapter pdfAdapter = new PdfDocumentAdapter(this, pdfFile.getAbsolutePath());
    printManager.print(printJobName, pdfAdapter, new PrintAttributes.Builder().build());
}

// 自定义PDF打印适配器
private class PdfDocumentAdapter extends PrintDocumentAdapter {
    private final Context context;
    private final String filePath;
    private PdfRenderer pdfRenderer;

    public PdfDocumentAdapter(Context context, String filePath) {
        this.context = context;
        this.filePath = filePath;
    }

    @Override
    public void onLayout(PrintAttributes oldAttrs, PrintAttributes newAttrs, CancellationSignal cancelSignal, LayoutResultCallback callback, Bundle extras) {
        if (cancelSignal.isCanceled()) {
            callback.onLayoutCancelled();
            return;
        }

        try {
            ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(new File(filePath), ParcelFileDescriptor.MODE_READ_ONLY);
            pdfRenderer = new PdfRenderer(fileDescriptor);
        } catch (IOException e) {
            callback.onLayoutFailed(e.getMessage());
            return;
        }

        PrintDocumentInfo docInfo = new PrintDocumentInfo.Builder("recycler_data.pdf")
                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                .setPageCount(pdfRenderer.getPageCount())
                .build();

        callback.onLayoutFinished(docInfo, false);
    }

    @Override
    public void onWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancelSignal, WriteResultCallback callback) {
        if (cancelSignal.isCanceled()) {
            callback.onWriteCancelled();
            return;
        }

        try {
            // 渲染PDF页面到打印输出流
            PdfRenderer.Page page = pdfRenderer.openPage(0);
            page.render(destination.getFileDescriptor(), null, null, PdfRenderer.Page.RENDER_MODE_FOR_PRINT);
            page.close();
        } catch (IOException e) {
            callback.onWriteFailed(e.getMessage());
            return;
        } finally {
            pdfRenderer.close();
        }

        callback.onWriteFinished(pages);
    }
}

5. 整合调用(按钮点击示例)

将数据获取、PDF生成、打印逻辑整合到点击事件中,注意耗时操作需放在子线程:

printBtn.setOnClickListener(v -> {
    new AsyncTask<Void, Void, File>() {
        @Override
        protected File doInBackground(Void... voids) {
            try {
                DBHelper dbHelper = new DBHelper(MainActivity.this);
                List<Item> itemList = dbHelper.getAllItems();
                return generatePDF(itemList);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(File pdfFile) {
            if (pdfFile != null && pdfFile.exists()) {
                printPDF(pdfFile);
            } else {
                Toast.makeText(MainActivity.this, "PDF生成失败", Toast.LENGTH_SHORT).show();
            }
        }
    }.execute();
});

若使用Kotlin,可替换AsyncTask为Coroutine实现异步操作,逻辑一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:48:15