简体   繁体   English

Android:PdfDocument 生成空的 pdf

[英]Android: PdfDocument generates empty pdf

        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);其中findViewById(R.id.textarea); refers to a TextView with some text, but the above code generates only empty pdf.指的是带有一些文本的TextView ,但上面的代码只生成空的 pdf。 What can be the issue?可能是什么问题?

is there any link that have working sample of generating pdf using Android native API?是否有任何链接具有使用 Android 本机 API 生成 pdf 的工作示例?

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.我有,但经过大量测试后,我意识到我的视图具有 0 高度和 0 宽度,因为我使用的是 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:所以我设法等到视图(TextView)加载并开始创建文档后,看看代码,希望你能修复它:

    @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
} 
        });

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:如果有人正在动态创建布局,并且没有将其视图附加到在 Activity 或 Fragment 生命周期中的某个时间点渲染和测量的 Activity 或 Fragment,则还有另一种方法:

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.这样你的 rootView 宽度和高度就不会保持为 0,并且会有一些东西会被渲染到文档中。 Courtesy of the answer here !感谢这里的答案

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 .对我帮助最大的例子是可以在Android Cookbook中找到的一个,你可以在他们的github帐户中找到相应的代码。

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);
    }
}

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我遇到了完全相同的问题,但为了实施 @user2021505 解决方案(有效),我应该进行重大重构,所以我以这种方式解决了这个问题

// ...
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()

First Of all, you need to add dependency首先需要添加依赖

implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.3.2'

Then Set bitmap on Blank PDf Documents然后在空白的 PDF 文档上设置位图

            PdfDocument pdfDocument =  new PdfDocument();
            PdfDocument.PageInfo pi = new 
            PdfDocument.PageInfo.Builder(mBitmap.getWidth(), 
            mBitmap.getHeight(),1).create();

            PdfDocument.Page page = pdfDocument.startPage(pi);
            Canvas canvas = page.getCanvas();
            Paint paint = new Paint();
            paint.setColor(Color.parseColor("#FFFFFF"));
            canvas.drawPaint(paint);

            mBitmap = Bitmap.createScaledBitmap(mBitmap, 
            mBitmap.getWidth(),mBitmap.getHeight(), true);
            paint.setColor(Color.BLUE);
            canvas.drawBitmap(mBitmap,0,0,null);
            pdfDocument.finishPage(page);
            pdfDocument.close();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM