Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: PdfDocument generates empty pdf

Tags:

android

        PdfDocument document = new PdfDocument();
        // crate a page description
        PageInfo pageInfo = new PageInfo.Builder(300, 300, 1).create();
        // create a new page from the PageInfo
        Page page = document.startPage(pageInfo);
        // repaint the user's text into the page
        View content = findViewById(R.id.textarea);
        content.draw(page.getCanvas());
        // do final processing of the page
        document.finishPage(page);
        try {
             File f = getPDFPath();
             FileOutputStream fos = new FileOutputStream(f);
             document.writeTo(fos);
             document.close();
             fos.close();

        } catch (IOException e) {
            throw new RuntimeException("Error generating file", e);
        }

Where findViewById(R.id.textarea); refers to a TextView with some text, but the above code generates only empty pdf. What can be the issue?

is there any link that have working sample of generating pdf using Android native API?

like image 552
Shahul Avatar asked Apr 09 '14 10:04

Shahul


2 Answers

i have the have, but after a lot of test, i realise that my View was with 0 heigth and 0 width, since i was using a TextView. So i managed to wait till view (TextView) will load and after start creating document, take a look at the code, hope you will fix it:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.fragment_main);

     final TextView tv = (TextView) findViewById(R.id.textView1);
        ViewTreeObserver vto = tv.getViewTreeObserver(); 
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
            @Override 
            public void onGlobalLayout() { 
                Toast.makeText(MainActivity.this, tv.getWidth() + " x " + tv.getHeight(), Toast.LENGTH_LONG).show();    

                try {
                    File file1 = new File("/mnt/sdcard/test/");
                    if(!file1.exists()){
                        file1.mkdirs();
                    }

                    File file = new File("/mnt/sdcard/test", "filename"+System.currentTimeMillis()+".pdf");
                    PrintAttributes printAttrs = new PrintAttributes.Builder().
                            setColorMode(PrintAttributes.COLOR_MODE_COLOR).
                            setMediaSize(PrintAttributes.MediaSize.ISO_A4).
                            setResolution(new Resolution("zooey", PRINT_SERVICE, 450, 700)).
                            setMinMargins(Margins.NO_MARGINS).
                            build();
                    PdfDocument document = new PrintedPdfDocument(MainActivity.this, printAttrs);
                     PageInfo pageInfo = new PageInfo.Builder(450, 700, 1).create();
                     Page page = document.startPage(pageInfo);

                     if (page != null) {

                           View view = findViewById(R.id.textView1);//getContentView();                          
                           view.layout(0, 0, view.getWidth(),
                                   view.getHeight());
                           Log.i("draw view", " content size: "+view.getWidth()+" / "+view.getHeight());
                           view.draw(page.getCanvas());
                           // Move the canvas for the next view.
                           page.getCanvas().translate(0, view.getHeight());
                       }    

                     document.finishPage(page);
                     os = new FileOutputStream(file);
                            document.writeTo(os);
                            document.close();
                            os.close();
                            Log.i("done", file.getAbsolutePath().toString());

                        } catch (IOException e) {
                            throw new RuntimeException("Error generating file", e);
                        }

                tv.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            } 
        });

}

the magic inside:

 final TextView tv = (TextView) findViewById(R.id.textView1);
        ViewTreeObserver vto = tv.getViewTreeObserver(); 
        vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
            @Override 
            public void onGlobalLayout() { 
         // create document here
} 
        });
like image 51
user2021505 Avatar answered Oct 28 '22 14:10

user2021505


If somebody is creating layout on the fly, and doesn't have its view attached to activity or fragment which gets rendered and measured at some point in activity or fragment lifecycle, there is another approach:

rootView.measure(800, 480);
rootView.layout(0, 0, 800, 480);

This way your rootView width and height will not stay 0 and there will be something that will be rendered to document. Courtesy of the answer here!

like image 20
Brcinho Avatar answered Oct 28 '22 13:10

Brcinho