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();
相关推荐
潜龙95278 小时前
第3.2.3节 Android动态调用链路的获取
android·调用链路
追随远方9 小时前
Android平台FFmpeg音视频开发深度指南
android·ffmpeg·音视频
撰卢10 小时前
MySQL 1366 - Incorrect string value:错误
android·数据库·mysql
恋猫de小郭10 小时前
Flutter 合并 ‘dot-shorthands‘ 语法糖,Dart 开始支持交叉编译
android·flutter·ios
牛马程序小猿猴10 小时前
15.thinkphp的上传功能
android
林家凌宇11 小时前
Flutter 3.29.3 花屏问题记录
android·flutter·skia
时丶光11 小时前
Android 查看 Logcat (可纯手机方式 无需电脑)
android·logcat
血手人屠喵帕斯11 小时前
事务连接池
android·adb
恋猫de小郭12 小时前
React Native 前瞻式重大更新 Skia & WebGPU & ThreeJS,未来可期
android·javascript·flutter·react native·react.js·ios
一人一萧十只猫�13 小时前
MySQL 从入门到精通(三):日志管理详解 —— 从排错到恢复的核心利器
android·mysql·adb