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
相关产品推荐
相关产品推荐

