Android 生成并加载PDF文件

  1. 使用系统提供的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();
         }
     }
  2. 加载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 文件并初始化 PdfRenderer
    public 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();
        }
    }

    // 渲染指定页面到 ImageView
    public 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);
    }

    // 关闭 PdfRenderer
    public 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.PDFView
        android: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() {
                    @Override
                    public 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() {
                    @Override
                    public 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();
相关推荐
阿巴斯甜18 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker18 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq952719 小时前
Andorid Google 登录接入文档
android
黄林晴21 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab1 天前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿1 天前
Android MediaPlayer 笔记
android
Jony_2 天前
Android 启动优化方案
android
阿巴斯甜2 天前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇2 天前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_2 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android