【问题标题】:Generating a PDF with custom size in android with PdfDocument使用 PdfDocument 在 android 中生成具有自定义大小的 PDF
【发布时间】:2020-01-18 02:19:26
【问题描述】:

PdfDocument 是一个可以从 Android 视图生成 PDF 的类。您只需将视图添加到PdfDocument,然后将 PDF 保存到内存中。

但是,我不想添加已经在屏幕中渲染的视图,因为这样的视图只适用于智能手机屏幕,并且我想为打印机生成 PDF 文档。

因此,我想传递一个不渲染的视图。虽然我当然可以这样做,但如何确定尺寸和比例?如何在我的 PDF 中控制它?

更新:

按照clotodex的以下答案,我做到了:

    LayoutInflater inflater = getLayoutInflater();
    View linearview;
    linearview = inflater.inflate(R.layout.printed_order,
                                  findViewById(android.R.id.content),
                                  false);

    PdfDocument document = new PdfDocument();
    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(2480, 3508, 0).create();
    PdfDocument.Page page = document.startPage(pageInfo);

    linearview.draw(page.getCanvas());
    document.finishPage(page);

    OutputStream outStream;
    File file = new File(getExternalFilesDir(null), "pedido.PDF");

    try {
        outStream = new FileOutputStream(file);
        document.writeTo(outStream);
        document.close();
        outStream.flush();
        outStream.close();

但我得到一个空的 PDF。如果我这样做了

View view = findViewById(android.R.id.content);
view.draw(page.getCanvas());

代替

linearview.draw(page.getCanvas()); 

我得到了我正在进行的活动,这证实了一切都是正确的,除了我试图打印的视图。

【问题讨论】:

  • “但我不知道这个错误来自 2 个布局中的哪一个”——嗯,它与其中一个中的第 18 行相关。追踪起来应该不会太难。或者,编辑您的问题并发布布局,也许有人可以指出哪一个有问题。
  • @CommonsWare 谢谢,我找到了。你能看看我的更新吗?
  • 使用inflater.inflate(R.layout.printed_order, null);,因为您不希望它出现在您的活动布局中。但是,您可能需要在draw() 之前调用measure()layout(),以匹配所需的页面大小(以像素为单位)。

标签: java android pdf


【解决方案1】:

看看这个问题render view off-screen in android

在 Android 中,视图的尺寸由父布局给出。 这意味着您可以使用所需的测量值创建新布局,并使用attachToRoot=falseroot=your_new_layout 扩展您的视图。

渲染视图后,您现在可以像将渲染视图绘制为 pdf 一样继续操作(按照链接中的说明或在绘制到页面画布之前将其转换为位图)。

【讨论】:

  • 你能看看我的更新吗?我几乎按照你说的做了,但我不知道如何创建我的根布局,并且出现大小错误
  • 我更新了更好的代码,现在可以生成 PDF 但它是空白的。可以看看吗?
  • 也许还没有测量布局?尝试将布局添加到您的活动中,然后再次绘制它,但通过 id 查找视图,或渲染整个内容,其中应包括您要打印的内容。
  • @lucas-zanella 您可以尝试关注this question 的答案。他们似乎也有类似的问题。您确实需要布局您的视图。 linearview.measure(...); 然后linearview.layout(0, 0, linearview.getMeasuredWidth(), linearview.getMeasuredHeight()); 如果这不起作用请再次评论。
【解决方案2】:

我想如果你只想打印成pdf,你可以使用PrintManager相关的API。详情可以看这个API

这是 pdf 的一些示例代码。

// method for PrintAdapter
override fun onLayout(
        oldAttributes: PrintAttributes?,
        newAttributes: PrintAttributes,
        cancellationSignal: CancellationSignal?,
        callback: LayoutResultCallback,
        extras: Bundle?
) {
    // Create a new PdfDocument with the requested page attributes
    pdfDocument = PrintedPdfDocument(activity, newAttributes)
    // Compute the expected number of printed pages
    val pages = computePageCount(newAttributes)
    if (pages > 0) {
        // Return print information to print framework
        PrintDocumentInfo.Builder("print_output.pdf")
                .setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
                .setPageCount(pages)
                .build()
                .also { info ->
                    // Content layout reflow is complete
                    callback.onLayoutFinished(info, true)
                }
    } else {
        // Otherwise report an error to the print framework
        callback.onLayoutFailed("Page count calculation failed.")
    }
}

【讨论】:

  • 不,我想要一种适合打印机的自定义布局,不同于显示数据的布局。我应该如何使用此布局而不将其呈现到屏幕上?
【解决方案3】:

我用PrintHelper你可以找到它的文档here

public void print() {
    if(PrintHelper.systemSupportsPrint()){
        final Bitmap bm;
        try {
              bm = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
              bm.eraseColor(Color.WHITE);// otherwise it will be trans
              final Canvas canvas = new Canvas(bm);
              drawOn(canvas)// draw on canvas
        }catch (OutOfMemoryError er) {
              // out of memory error
              return;
        }
        if(bm == null) return;
        final PrintHelper printHelper = new PrintHelper(getContext());
        printHelper.setScaleMode(PrintHelper.SCALE_MODE_FIT);
        printHelper.printBitmap("fileName", bm, new PrintHelper.OnPrintFinishCallback() {
                @Override
                public void onFinish() {
                        bm.recycle();
                }
            });

    }else{
            // print not supported
    }
}

【讨论】:

    猜你喜欢
    • 2017-02-21
    • 2015-03-12
    • 2018-03-12
    • 2016-01-18
    • 1970-01-01
    • 1970-01-01
    • 2016-03-19
    • 1970-01-01
    • 2014-05-13
    相关资源
    最近更新 更多