- 使用系统提供的PdfDocument 生成pdf文件
public static void createPdf(Context context, String fileName) {// 创建 PdfDocument 实例PdfDocument pdfDocument = new PdfDocument();// 创建一个页面描述信息,指定页面大小(如A4纸张大小)PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(595, 842, 1).create();// 开始一个页面PdfDocument.Page page = pdfDocument.startPage(pageInfo);// 获取页面的 Canvas,绘制内容Canvas canvas = page.getCanvas();Paint paint = new Paint();paint.setTextSize(16);paint.setColor(android.graphics.Color.BLACK);// 在页面上绘制文本canvas.drawText("谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢", 50, 50, paint);// 完成当前页面的内容pdfDocument.finishPage(page);// 指定 PDF 文件的保存路径File pdfDir = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "MyPDFs");if (!pdfDir.exists()) {pdfDir.mkdirs();}File pdfFile = new File(pdfDir, fileName + ".pdf");// 写入 PDF 文件try (FileOutputStream fos = new FileOutputStream(pdfFile)) {pdfDocument.writeTo(fos);fos.flush();} catch (IOException e) {e.printStackTrace();} finally {pdfDocument.close();}}
- 加载pdf文件有三种方法
2.1 使用系统或者三方pdf查看器
File pdfFile = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS), "MyPDFs/example.pdf");
Uri pdfUri = Uri.fromFile(pdfFile);Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(pdfUri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);if (intent.resolveActivity(getPackageManager()) != null) {startActivity(intent);
} else {// 提示用户没有安装 PDF 查看器
}
2.2 使用系统提供的PdfRenderer加载,不过需要5.1以上
private PdfRenderer pdfRenderer;private PdfRenderer.Page currentPage;// 打开 PDF 文件并初始化 PdfRendererpublic void openPdf(Context context, File pdfFile, ImageView imageView) {try {ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY);pdfRenderer = new PdfRenderer(fileDescriptor);// 显示第一页showPage(0, imageView);} catch (IOException e) {e.printStackTrace();}}// 渲染指定页面到 ImageViewpublic void showPage(int pageIndex, ImageView imageView) {if (pdfRenderer == null || pageIndex < 0 || pageIndex >= pdfRenderer.getPageCount()) {return;}// 关闭之前的页面if (currentPage != null) {currentPage.close();}// 打开指定页面currentPage = pdfRenderer.openPage(pageIndex);// 创建 Bitmap 并渲染页面内容Bitmap bitmap = Bitmap.createBitmap(currentPage.getWidth(), currentPage.getHeight(), Bitmap.Config.ARGB_8888);currentPage.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);// 显示渲染后的页面imageView.setImageBitmap(bitmap);}// 关闭 PdfRendererpublic void closePdf() {if (currentPage != null) {currentPage.close();}if (pdfRenderer != null) {pdfRenderer.close();}}
2.3 三方依赖库查看
implementation 'com.github.barteksc:android-pdf-viewer:3.1.0-beta.1'<com.github.barteksc.pdfviewer.PDFViewandroid:id="@+id/pdf_view"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@color/transparent"/>PDFView mPdfView;private String mPdfFilePath;private File mPdfFile = new File(mPdfFilePath);mPdfView.useBestQuality(true);mPdfView.fromFile(mPdfFile).enableSwipe(true) // allows to block changing pages using swipe.swipeHorizontal(false).enableDoubletap(true).defaultPage(0).onLoad(nbPages -> Timber.e("pdf loadComplete %d", nbPages)) // called after document is loaded and starts to be rendered.onPageChange((page, pageCount) -> Timber.e("pdf onPageChanged page %d pageCount %d", page, pageCount)).onPageScroll((page, positionOffset) -> Timber.e("pdf onPageScrolled page %d positionOffset %s", page, positionOffset)).onError(Throwable::printStackTrace).onPageError((page, t) -> {Timber.e("pdf onPageError page %d", page);t.printStackTrace();}).onRender(new OnRenderListener() {@Overridepublic void onInitiallyRendered(int nbPages) {Timber.e("pdf onInitiallyRendered nbPages %d", nbPages);}}) // called after document is rendered for the first time.enableAnnotationRendering(false) // render annotations (such as comments, colors or forms).password(null).scrollHandle(null).enableAntialiasing(true) // improve rendering a little bit on low-res screens.spacing(8) // spacing between pages in dp. To define spacing color, set view background.autoSpacing(false) // add dynamic spacing to fit each page on its own on the screen.linkHandler(new LinkHandler() {@Overridepublic void handleLinkEvent(LinkTapEvent event) {Timber.e("pdf handleLinkEvent");String uri = event.getLink().getUri();Integer page = event.getLink().getDestPageIdx();if (uri != null && !uri.isEmpty()) {handleUri(uri);} else if (page != null) {handlePage(page);}}private void handleUri(String uri) {if (RegexUtils.isURL(uri)) {HtmlActivity.open(mContext, uri, uri);}}private void handlePage(int page) {mPdfView.jumpTo(page);}}).pageFitPolicy(FitPolicy.WIDTH).pageSnap(false) // snap pages to screen boundaries.pageFling(false) // make a fling change only a single page like ViewPager.nightMode(false) // toggle night mode.load();