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();
相关推荐
幼稚园的山代王8 分钟前
Kotlin-基础语法练习一
android·开发语言·kotlin
闻不多13 分钟前
用llamaindex搭建GAR遇到400
android·运维·服务器
阿华的代码王国23 分钟前
【Android】适配器与外部事件的交互
android·xml·java·前端·后端·交互
跨界混迹车辆网的Android工程师1 小时前
实现Android图片手势缩放功能的完整自定义View方案,结合了多种手势交互功能
android·交互
wyjcxyyy1 小时前
打靶日记-PHPSerialize
android
安卓开发者12 小时前
Android RxJava 组合操作符实战:优雅处理多数据源
android·rxjava
阿华的代码王国12 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼12 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jerry说前后端13 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
alexhilton13 小时前
深入浅出着色器:极坐标系与炫酷环形进度条
android·kotlin·android jetpack