Android 使用PdfDocument生成PDF文件及遇到的问题

一、PdfDocument使用

     PdfDocument是Android原生的生成pdf文件的类,这个类的使用可参考:

 https://developer.android.google.cn/reference/kotlin/android/graphics/pdf/PdfDocument

 https://blog.csdn.net/tangedegushi/article/details/81502394

二、问题及解决

背景:需要动态加载一个View,View里面的内容也是动态添加的(比如动态添加多个TextView)。将View的内容生成Pdf文件。

问题: 生成的pdf是空白的?

解决:发现直接添加在布局文件里的内容可以在生成的PDF文件中显示,而动态添加的显示不出来。查找资料发现

https://blog.csdn.net/weixin_40022240/article/details/80692596,应该是因为动态生成的View没有进行Measure 和Layout 所以没有绘制出来,添加上果然就可以了,问题解决。

实例:

布局文件:




    
        
    

代码: 根据数据向LinearLayout内动态添加绘制了心电图的View,之后将View生成pdf文件

 public void generatePdf(String historyTime){
        String pdfFilePath = BASE_PATH + File.separator + historyTime+".pdf";
        File pdfFile = new File(pdfFilePath);
        File baseFile = new File(BASE_PATH);
        if(!baseFile.exists()) {
            baseFile.mkdir(); 
        }

        if(pdfFile.exists()){
            pdfFile.delete();
        }


        int onePageHeight = Utils.dip2px(mContext, 250)*2;  //每页高度
        int pdfCount = ecgNum/2;                            //总页数
        PdfDocument document = new PdfDocument();//1, 建立PdfDocument

      /*  生成单页
       PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo
                .Builder(1080, onePageHeight, 1)
               // .setContentRect(new Rect(0,60,1080,onePageHeight+60))
                .create();//2 crate a page description
        PdfDocument.Page page = document.startPage(pageInfo); //3、start a page
        Canvas canvas = page.getCanvas();
        Log.d("tzw","the mLlEcgPdf width:"+mLlEcgPdf.getWidth()+ "; height:"+mLlEcgPdf.getHeight());

       measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), //2, 测量大小
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
       layout(0, 0,mLlEcgPdf.getMeasuredWidth(), mLlEcgPdf.getMeasuredHeight()); //3, 测量位置

        draw(canvas);
        document.finishPage(page);///5、finish the page
*/

//生成多页的pdf
        for (int i = 0; i < pdfCount; i++) {
            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo
                    .Builder(1080, onePageHeight, pdfCount)
                   //  .setContentRect(new Rect(0,60,mLlEcgPdf.getWidth(),onePageHeight+60))
                    .create();//2 crate a page description
            PdfDocument.Page page = document.startPage(pageInfo); //3、start a page
            Canvas canvas = page.getCanvas();
            canvas.translate(0,-onePageHeight*i);
            measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), // 测量大小
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
            layout(0, 0,mLlEcgPdf.getMeasuredWidth(), mLlEcgPdf.getMeasuredHeight()); // 测量位置
            mLlEcgPdf.draw(canvas);//4、 draw something on the page
            document.finishPage(page);///5、finish the page
        }

        try {
            document.writeTo(new FileOutputStream(pdfFile)); //write the document content
            // Toast.makeText(ECGActivity.this,"文件已生成,存储路径:"+BASE_PATH ,Toast.LENGTH_SHORT).show();
            AlertDialog dialog = new AlertDialog.Builder(mContext).setTitle("").setMessage("文件已生成,存储路径:"+BASE_PATH).create();
            dialog.show();
        } catch (IOException e) {
            e.printStackTrace();
        }

        document.close(); //close the document

    }

重点就是添加

    measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), //2, 测量大小
                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
    layout(0, 0,mLlEcgPdf.getMeasuredWidth(), mLlEcgPdf.getMeasuredHeight()); //3, 测量位置
    mLlEcgPdf.draw(canvas);

通过测量measure,布局layout,绘制draw,将动态添加的View绘制出来,注意这里的MeasureSpec是unspecified, 我们的pdfview并没有一个父控件,随意高宽不必受约束,layout也是确定子控件的位置。没有上面代码将导致生成的Pdf 空白。

其中生成多页的Pdf文件参考:

https://blog.csdn.net/MikoGodZd/article/details/51767848

 

你可能感兴趣的:(Android)