Android PDFDocument正在生成一个空白文档

时间:2016-06-11 12:49:49

标签: android android-studio pdf-generation

我正在使用Android Studio并试图让我的应用程序生成PDF。我已经设置了一个Activity,它会生成我想要PDF的内容。如果我让它显示在屏幕上,这可以正常工作。活动的onCreate部分如下:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Connect to database
    connectToDatabase();

    // Set view
    setContentView(R.layout.activity_export_pattern);

    // find various views and set up their contents 
    // (I've left this bit out as it's quite long, but it doesn't contain 
    // anything controversial)

    // Now try to export to PDF.  
    // Return success or failure to calling activity 
    //  (basically just displays a toast indicating success/failure)
    try {
        if(exportToPDF()) {
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_OK, returnIntent);
            finish();
        }else {
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_CANCELED, returnIntent);
            finish();
        }
    } catch (IOException e) {
        e.printStackTrace();
        Intent returnIntent = new Intent();
        setResult(Activity.RESULT_CANCELED, returnIntent);
        finish();
    }
}

如果我省略了最后一部分(try-catch),只是让它显示在屏幕上,它就可以正常工作。屏幕显示我希望它显示的内容。

但是,为了让它创建PDF,我使用try-catch和exportToPDF调用,它包含以下代码(这基本上是Android文档中的代码,如下面的注释所示,有一些更改):

   public boolean exportToPDF() {
        // Create PDF document
        PdfDocument document = new PdfDocument();
        // Create page description
        // Line below changed as Android Studio was highlighting an error; 
        //  instead of Rect, I have just put numbers.
        //  I've varied the numbers from 100 up to 1000, to no effect
        PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(720, 720, 1).create();
        // Start page
        PdfDocument.Page page = document.startPage(pageInfo);
        // Changed the line below from content = getContentView, as that was causing an error
        // pageContent is the id of the overall LinearLayout in the XML file
        // If I break after this in the debugger, content seems to have found the correct view and be populated with the appropriate page elements
        View content =  this.findViewById(R.id.pageContent);
        // Added the line below after finding it suggested on here in another question
        //  Doesn't seem to make any difference
        content.layout(0, 0, 200, 200);
        if (content != null) {
            content.draw(page.getCanvas());
        }
        // Finish page
        document.finishPage(page);

        // Write document content to external storage
        // I'm using a FileOutputStream instead of BufferedOutputStream as given in the documentation, but, since this does at least produce a file, I don't think this is the source of the problem
        String filename = this.item.getName() + ".pdf";
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/" + filename);
        FileOutputStream fileOut = null;
        try {
            fileOut = new FileOutputStream(file);
            document.writeTo(fileOut);
            fileOut.close();
            document.close();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            if(fileOut != null) fileOut.close();
            document.close();
            return false;
        }
    }

因此,运行它会在正确的目录中生成一个PDF,命名正确,但它是空白的。我不知道还有什么可以尝试。

1 个答案:

答案 0 :(得分:2)

如果您在活动中将视图写入PDF onCreate(),它将无法工作,因为您的视图返回0高度和宽度。您需要等待附加活动窗口,然后将视图写入pdf。您可以尝试从活动的onWindowFocusChanged()方法调用exportToPDF。

public void onWindowFocusChanged(boolean hasFocus) {
    // TODO Auto-generated method stub
    super.onWindowFocusChanged(hasFocus);
try {
        if(exportToPDF()) {
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_OK, returnIntent);
            finish();
        }else {
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_CANCELED, returnIntent);
            finish();
        }
    } catch (IOException e) {
        e.printStackTrace();
        Intent returnIntent = new Intent();
        setResult(Activity.RESULT_CANCELED, returnIntent);
        finish();
    }

    }

您也可以使用ViewTreeObserver

 View content =  this.findViewById(R.id.pageContent);
    ViewTreeObserver vto = content.getViewTreeObserver(); 
            vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
                @Override 
                public void onGlobalLayout() { 
              try {
            if(exportToPDF()) {
                Intent returnIntent = new Intent();
                setResult(Activity.RESULT_OK, returnIntent);
                finish();
            }else {
                Intent returnIntent = new Intent();
                setResult(Activity.RESULT_CANCELED, returnIntent);
                finish();
            }
        } catch (IOException e) {
            e.printStackTrace();
            Intent returnIntent = new Intent();
            setResult(Activity.RESULT_CANCELED, returnIntent);
            finish();
        }
content.getViewTreeObserver().removeGlobalOnLayoutListener(this);
    } 
            });