如何将Android视图转换为PDF

19

我创建了一个Android发票应用程序。生成的发票是带有嵌套视图的标准Android布局。我正在寻找一个库,可以用来将此视图转换为pdf文档。

我很惊讶我的搜索中没有直截了当的选项,或者说我可能已经把第一件事做在了最后。或者我所寻找的可能不可行。

请有人帮助我指向一个工具,它将帮助我从Android视图中转换或生成PDF。我愿意尝试免费和适度付费的选项。或者让我知道我所寻找的是否可行。

4个回答

17

看一下您的设备屏幕:

Bitmap screen;
View v1 = MyView.getRootView();
v1.setDrawingCacheEnabled(true);
screen= Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);

如果您将ScrollView作为根视图,则:

LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
RelativeLayout root = (RelativeLayout) inflater.inflate(R.layout.activity_main, null); //RelativeLayout is root view of my UI(xml) file.
root.setDrawingCacheEnabled(true);
Bitmap screen= getBitmapFromView(this.getWindow().findViewById(R.id.relativelayout)); // here give id of our root layout (here its my RelativeLayout's id)

这里是getBitmapFromView()方法:

public static Bitmap getBitmapFromView(View view) {
    //Define a bitmap with the same size as the view
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
    //Bind a canvas to it
    Canvas canvas = new Canvas(returnedBitmap);
    //Get the view's background
    Drawable bgDrawable =view.getBackground();
    if (bgDrawable!=null) 
        //has background drawable, then draw it on the canvas
        bgDrawable.draw(canvas);
    else 
        //does not have background drawable, then draw white background on the canvas
        canvas.drawColor(Color.WHITE);
    // draw the view on the canvas
    view.draw(canvas);
    //return the bitmap
    return returnedBitmap;
}

它将显示整个屏幕,包括在您的 ScrollView 中隐藏的内容。 现在我们有了位图屏幕,让我们将其保存为PDF(您必须下载 itextpdf-5.3.2.jar 文件并附加到项目中...)

private static String FILE = "mnt/sdcard/invoice.pdf"; // add permission in your manifest...

try 
{
    Document document = new Document();

    PdfWriter.getInstance(document, new FileOutputStream(FILE));
    document.open();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    screen.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] byteArray = stream.toByteArray();
    addImage(document,byteArray);
    document.close();
}

catch (Exception e) 
{
    e.printStackTrace();
}

private static void addImage(Document document,byte[] byteArray) 
{
    try 
    {
        image = Image.getInstance(byteArray);  
    } 
    catch (BadElementException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (MalformedURLException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    catch (IOException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
     // image.scaleAbsolute(150f, 150f);
      try 
      {
        document.add(image);
    } catch (DocumentException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

我没有进行过任何测试。这是我使用的所有来源:source1source2source3


2
谢谢,绝妙的想法,它几乎可以工作。然而,它截取了包括Actionbar在内的所有内容的屏幕截图。最终的PDF也有点模糊。再次感谢您的建议。它开启了我的眼界,我将继续寻找其他替代方案。再次感谢您的巨大贡献。 - Val Okafor
看起来非常有趣,但是你不需要支付文本许可证费用吗? - david
是的@Marco Dufai,这很痛苦,我实际上不得不从Play商店撤下我的应用程序并探索其他选择。我花了三个月时间编写我的发票应用程序,PDF生成只是其中的一小部分。我写信给公司,他们以书面形式向我确认,我需要为每次下载应用程序支付年度许可证费用。所以我现在取消发布该应用程序。一定要注意许可证,不是所有开源都是免费的。 - Val Okafor
@ValOkafor 很抱歉...我甚至不知道这件事...正如我在答案结尾所述,我只是在这个网站周围收集了所有可能实现我的初始想法的资源...无论如何,至少我们在评论部分指出了这一点,这是一件好事,对吧? - n1nsa1d00
1
我正在使用相同的代码,但只能看到一半的PDF,请问有人可以帮助我吗? - Nikhil Singh
显示剩余5条评论

5

您可以使用自定义库,例如https://github.com/HendrixString/Android-PdfMyXml。我更喜欢这个库而不是其他方法。只需按照以下步骤进行操作。

但还有另一种方法 - 如何将Android视图转换为PDF - 生成包含布局位图的PDF。


2

在不使用第三方库的情况下,您可以使用Android API 19中引入的PdfDocument。但是,请记住,PDF文件的尺寸将以后置点(1/72英寸)为单位。因此,在绘制到画布之前,您必须将视图的尺寸转换为匹配要求。


2
我创建了一个图书馆来实现这个目标(从Java视图对象获取PDF)。
主要的代码片段是:-
 PdfGenerator.getBuilder()
                        .setContext(context)
                        .fromViewSource()
                        .fromView(targetView) /* "targetView" is the view ,you want to convert PDF */
            /* "fromLayoutXML()" takes array of layout resources.
             * You can also invoke "fromLayoutXMLList()" method here which takes list of layout resources instead of array. */
                        .setDefaultPageSize(PdfGenerator.PageSize.A4)
            /* It takes default page size like A4,A5. You can also set custom page size in pixel
             * by calling ".setCustomPageSize(int widthInPX, int heightInPX)" here. */
                        .setFileName("Test-PDF")
            /* It is file name */
                        .setFolderName("FolderA/FolderB/FolderC")
            /* It is folder name. If you set the folder name like this pattern (FolderA/FolderB/FolderC), then
             * FolderA creates first.Then FolderB inside FolderB and also FolderC inside the FolderB and finally
             * the pdf file named "Test-PDF.pdf" will be store inside the FolderB. */
                        .openPDFafterGeneration(true)
            /* It true then the generated pdf will be shown after generated. */
                        .build(new PdfGeneratorListener() {
                            @Override
                            public void onFailure(FailureResponse failureResponse) {
                                super.onFailure(failureResponse);
                /* If pdf is not generated by an error then you will findout the reason behind it
                 * from this FailureResponse. */
                            }

                            @Override
                            public void showLog(String log) {
                                super.showLog(log);
                /*It shows logs of events inside the pdf generation process*/ 
                            }

                            @Override
                            public void onSuccess(SuccessResponse response) {
                                super.onSuccess(response);
                /* If PDF is generated successfully then you will find SuccessResponse 
                 * which holds the PdfDocument,File and path (where generated pdf is stored)*/
                
                            }
                        });

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接