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();
相关推荐
Hacker_Albert1 分钟前
OpenHarmony-1.启动流程
android·java·服务器
郝晨妤1 小时前
HarmonyOS和OpenHarmony区别是什么?鸿蒙和安卓IOS的区别是什么?
android·ios·harmonyos·鸿蒙
烬奇小云5 小时前
认识一下Unicorn
android·python·安全·系统安全
顾北川_野18 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO18 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他18 小时前
Android ANR分析总结
android
PenguinLetsGo19 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博1 天前
音频格式转换
android·音视频
音视频牛哥1 天前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.1 天前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda