Android 生成并加载PDF文件
- 使用系统提供的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 文件并初始化 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();