Android: PdfDocument generates empty pdf

前端 未结 4 1521
无人及你
无人及你 2020-12-14 19:20
        PdfDocument document = new PdfDocument();
        // crate a page description
        PageInfo pageInfo = new PageInfo.Builder(300, 300, 1).create();
                


        
相关标签:
4条回答
  • 2020-12-14 19:57

    The example that has helped me the most is the one that it can be found in the Android Cookbook You can find the corresponding code in their github account.

    Mix that code with the one for writing and you will have it:

    @TargetApi(Build.VERSION_CODES.KITKAT)
    public void run() {
        // Create a shiny new (but blank) PDF document in memory
        // We want it to optionally be printable, so add PrintAttributes
        // and use a PrintedPdfDocument. Simpler: new PdfDocument().
        PrintAttributes printAttrs = new PrintAttributes.Builder().
                setColorMode(PrintAttributes.COLOR_MODE_COLOR).
                setMediaSize(PrintAttributes.MediaSize.NA_LETTER).
                setResolution(new PrintAttributes.Resolution("zooey", PRINT_SERVICE, 300, 300)).
                setMinMargins(PrintAttributes.Margins.NO_MARGINS).
                build();
        PdfDocument document = new PrintedPdfDocument(this, printAttrs);
        // crate a page description
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(300, 300, 1).create();
        // create a new page from the PageInfo
        PdfDocument.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);
        // Here you could add more pages in a longer doc app, but you'd have
        // to handle page-breaking yourself in e.g., write your own word processor...
        // Now write the PDF document to a file; it actually needs to be a file
        // since the Share mechanism can't accept a byte[]. though it can
        // accept a String/CharSequence. Meh.
        try {
            File f = new File(Environment.getExternalStorageDirectory().getPath() + "/pruebaAppModerator.pdf");
            FileOutputStream fos = new FileOutputStream(f);
            document.writeTo(fos);
            document.close();
            fos.close();            
        } catch (IOException e) {
            throw new RuntimeException("Error generating file", e);
        }
    }
    
    0 讨论(0)
  • 2020-12-14 19:59

    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!

    0 讨论(0)
  • 2020-12-14 20:00

    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
    } 
            });
    
    0 讨论(0)
  • 2020-12-14 20:22

    I had the exact same problem but in order to implement @user2021505 solution (that works) I should have done a major refactor, so I solved the issue this way

    // ...
    PdfDocument.Page page = document.startPage(pageInfo);
    
    TextView textView = new TextView(ctx);
    textView.setText("1,2,3");
    
    // here the solution
    int left = 0;
    int top = 0;
    int width = 200;
    int height = 200;
    textView.layout(0,0,width,height);
    
    canvas.save()
    canvas.translate(left,top);
    
    textView.draw(page.getCanvas());
    
    canvas.restore()
    
    0 讨论(0)
提交回复
热议问题