Vin*_*ina 19 printing pdf android webview
我正在开发一个应用程序(Android 4.4 - API 20),我正在生成HTML格式的报告.我使用WebView对象在我的应用程序中显示报表.
我希望能够做的是将此WebView转换为pdf文档.
我已经能够使用PdfDocument转换它,并从WebView对象执行.draw到页面.我保存文件,这是有效的,但结果是单页文档.没有分页符.
View content = (View) webView;
PrintAttributes pdfPrintAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER.asLandscape()).
setResolution(new Resolution("zooey", PRINT_SERVICE, 300, 300)).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).
build();
PdfDocument document = new PrintedPdfDocument(mContext,pdfPrintAttrs);
PageInfo pageInfo = new PageInfo.Builder(webView.getMeasuredWidth(), webView.getContentHeight(), 1).create();
Page page = document.startPage(pageInfo);
content.draw(page.getCanvas());
document.finishPage(page);
Run Code Online (Sandbox Code Playgroud)
如果我更改它以便我使用PrintedPdfDocumet并且不指定PageInfo我只获取WebView对象的可查看部分.
View content = (View) webView;
PrintAttributes pdfPrintAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER.asLandscape()).
setResolution(new Resolution("zooey", PRINT_SERVICE, 300, 300)).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).
build();
PrintedPdfDocument document = new PrintedPdfDocument(mContext,pdfPrintAttrs);
Page page = document.startPage(0);
content.draw(page.getCanvas());
document.finishPage(page);
Run Code Online (Sandbox Code Playgroud)
如果我使用PrintManager并使用createPrintDocumentAdapter从WebView对象创建打印适配器,我可以选择"另存为PDF"选项,生成的pdf文件具有我在原始网页的CSS中指定的分页符.
PrintManager printManager = (PrintManager) getSystemService(Context.PRINT_SERVICE);
PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter();
String jobName = getString(R.string.app_name) + " Report "
+ reportName;
PrintAttributes printAttrs = new PrintAttributes.Builder().
setColorMode(PrintAttributes.COLOR_MODE_MONOCHROME).
setMediaSize(PrintAttributes.MediaSize.NA_LETTER.asLandscape()).
setMinMargins(PrintAttributes.Margins.NO_MARGINS).
build();
PrintJob printJob = printManager.print(jobName, printAdapter,
printAttrs);
Run Code Online (Sandbox Code Playgroud)
我的问题是:我是否可以指定我希望PrintManager执行"另存为PDF"并提供生成的文件的名称和位置,以便不与用户进行交互?
或者:有没有办法可以将我的WebView对象转换为PDF并允许分页.
这可能是一个迟到的答案,但到目前为止我还需要与Print Framework类似的解决方案,并且我将Pdf文档拆分成下面代码的页面.
据我所知,你无法真正让WebView或Pdf文档以一种聪明的方式将你的pdf文件分割成页面(不切割文本或图像).但我们能做的是以A4或Letter大小的比例创建Pages,因此它可以适合打印出纸张格式.
但是我还面临另一个问题.下面的代码在Android 4.4中按预期工作,但在以后的版本中没有.在Android-L中,只有WebView的可见部分被绘制到Pdf文件中,但是WebView中其余HTML的空白页面被绘制.
根据文件,
public static void enableSlowWholeDocumentDraw()
对于针对L版本的应用程序,WebView具有一种新的默认行为,可通过智能选择需要绘制的HTML文档部分来减少内存占用并提高性能.这些优化对开发人员来说是透明的.但是,在某些情况下,App开发人员可能希望禁用它们:
- 当应用程序使用onDraw(Canvas)来执行自己的绘图并访问页面的某些部分时,这些部分位于页面的可见部分之外.
- 当应用程序使用capturePicture()捕获非常大的HTML文档时.请注意,capturePicture是不推荐使用的API.
启用绘制整个HTML文档会产生显着的性能成本.应在创建任何WebView之前调用此方法.
我已经创建了一个Bug报告,并在此处评论了类似的错误报告,但到目前为止还没有回复.但在此之前,您可以使用下面的代码.
/**
* Creates a PDF Multi Page Document depending on the Ratio of Letter Size.
* This method does not close the Document. It should be Closed after writing Pdf Document to a File.
*
* @return
*/
private PdfDocument createMultiPagePdfDocument(int webViewWidth, int webViewHeight) {
/* Find the Letter Size Height depending on the Letter Size Ratio and given Page Width */
int letterSizeHeight = getLetterSizeHeight(webViewWidth);
PdfDocument document = new PrintedPdfDocument(getActivity(), getPrintAttributes());
final int numberOfPages = (webViewHeight/letterSizeHeight) + 1;
for (int i = 0; i < numberOfPages; i++) {
int webMarginTop = i*letterSizeHeight;
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(webViewWidth, letterSizeHeight, i+1).create();
PdfDocument.Page page = document.startPage(pageInfo);
/* Scale Canvas */
page.getCanvas().translate(0, -webMarginTop);
mWebView.draw(page.getCanvas());
document.finishPage(page);
}
return document;
}
/**
* Calculates the Letter Size Paper's Height depending on the LetterSize Dimensions and Given width.
*
* @param width
* @return
*/
private int getLetterSizeHeight(int width) {
return (int)((float)(11*width)/8.5);
}
Run Code Online (Sandbox Code Playgroud)
小智 2
不确定这是否能解决您的分页问题,但您是否考虑过使用开源 wkHTMLtoPDF 库 ( http://wkhtmltopdf.org/ ) 将 HTML 转换为 PDF?我们通过创建一个向其传递 HTML 代码的微服务来广泛使用它,然后让该服务将其转换为 PDF 并返回 PDF 的链接,或者让它返回 PDF(取决于大小)。我知道使用外部服务进行转换可能会很痛苦(或者您可能无法从设备访问互联网),但如果这不是问题,那么这可能是一个选择。可能还有其他 API 可用于执行此转换。Neutrino API就是这样的 API 之一。还有许多其他 - 您可以使用以下 API 搜索引擎之一来搜索 API: