使用 Android 19 打印 API,我尝试将 WebView 的内容直接渲染到设备存储上的 PDF 文件中。我知道我可以将 PrintJob
发送到 PrintManager
并让用户在那里选择“另存为 PDF”,但我不希望这样做。我想立即从我的应用程序保存 PDF。
我尝试使用 WebView.draw(PdfDocument.Page.getCanvas())
,但生成的 PDF 是光栅,而不是矢量 😕 Here's the result (文本不可选,也可以尝试缩放)以下代码:
final String htmlDocument = "<html><body><h1>Test Content</h1><p>Testing, testing, testing...</p></body></html>";
webView.loadDataWithBaseURL(null, htmlDocument, "text/HTML", "UTF-8", null);
// ...The following is on web view client's onPageFinished()
final PrintAttributes attrs = new PrintAttributes.Builder()
.setColorMode(PrintAttributes.COLOR_MODE_COLOR)
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.setMinMargins(PrintAttributes.Margins.NO_MARGINS)
.setResolution(new PrintAttributes.Resolution("1", "label", 300, 300))
.build();
final PrintedPdfDocument document = new PrintedPdfDocument(this, attrs);
final PdfDocument.Page page = document.startPage(1);
webView.draw(page.getCanvas());
// Also tried: webView.capturePicture().draw(page.getCanvas());
document.finishPage(page);
final FileOutputStream outputStream = new FileOutputStream(new File(Environment.getExternalStorageDirectory(), "test.pdf"));
document.writeTo(outputStream);
outputStream.close();
document.close();
鉴于将 PrintJob
发送到 PrintManager
会生成带有可选文本的漂亮矢量 PDF,我在阅读打印作业的工作原理后尝试直接使用这些 API:
final PrintDocumentAdapter webViewPrintAdapter = webView.createPrintDocumentAdapter();
outputFile = new File(Environment.getExternalStorageDirectory(), "test2.pdf");
final ParcelFileDescriptor fileDescriptor = ParcelFileDescriptor.open(outputFile, ParcelFileDescriptor.MODE_CREATE | ParcelFileDescriptor.MODE_READ_WRITE);
webViewPrintAdapter.onStart();
webViewPrintAdapter.onLayout(attrs, attrs, new CancellationSignal(), null, new Bundle());
webViewPrintAdapter.onWrite(new PageRange[]{ PageRange.ALL_PAGES }, fileDescriptor, new CancellationSignal(), null);
webViewPrintAdapter.onFinish();
上面的代码由于具有两个 null
回调的 NPE 而崩溃。问题是,我无法实现这些回调的 stub ,因为 LayoutResultCallback
和 WriteResultCallback
受包保护。
所以,我的问题是:
真的有可能实现我在这里想要实现的目标吗?我的意思是,不使用系统的打印机 UI 从 Web View 制作 PDF?
为什么
WebView.draw(PdfDocument.Page.getCanvas())
会生成带有不可选择文本的光栅 PDF?是否可以利用 Web View 本身创建的打印适配器,就像我在第二个示例中尝试做的那样?
谢谢。
最佳答案
Using Android 19 print APIs, I'm trying to render the content of a WebView directly into a PDF file on device storage.
打印 API 用于打印。它们从未用于创建 PDF 文件。
Why the WebView.draw(PdfDocument.Page.getCanvas()) produces a raster PDF with non-selectable text?
draw()
将 UI 渲染到 Canvas
,而不管源 UI(EditText
、Button
) 、ImageView
、ViewPager
、WebView
、ConstraintLayout
中的一些小部件组合等)。如果 Canvas
由 Bitmap
支持(他们可能在这里使用),您将获得一个 Bitmap
。
Is it somehow possible to make use of the print adapter created by the web view itself, like I was trying to do in the second example?
您可以尝试将 LayoutResultCallback
和 WriteResultCallback
的实现放入应用程序的 android.print
包中,方法是将 Java 包添加为您项目的一部分。俗话说,YMMV。
关于android - 将 WebView HTML 内容直接打印到 PDF 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48500382/