【问题标题】:How to turn xml layout to PDF report?如何将xml布局转换为PDF报告?
【发布时间】:2021-07-22 15:12:55
【问题描述】:

enter image description here我已经在android studio中用XML创建了一个报表布局。单击布局上的“生成”按钮后,我需要将布局转换为 PDF 格式。有没有可能使它成为可能?提前谢谢!

我想将该布局中的数据转换为该确切表格中的 pdf

【问题讨论】:

    标签: android-studio android-layout pdf button


    【解决方案1】:

    用于生成pdf:

    ->在manifest的External Storage中添加读写权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    

    ->点击生成pdf按钮,检查权限是否被授予。

    点击按钮试试这个代码:

     /*check read/write storage permission is granted or not*/
     if(checkPermissionGranted()){
       convertToPdf();
     }else{
       requestPermission();
     }
    

    checkPermissionGranted() 方法:

     private boolean checkPermissionGranted(){
            if((ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
                    && (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)) {
                // Permission has already been granted
                return  true;
            } else {
                return false;
            }
        }
    

    requestPermission() 方法:

     private void requestPermission(){
            ActivityCompat.requestPermissions(LayoutToPdfActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
        }
    

    覆盖 onActivityResult 方法:

    @Override
        protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
            super.onActivityResult(requestCode, resultCode, data);
            if(requestCode == 1) {
                if (resultCode == Activity.RESULT_OK) {
                    convertToPdf();
                }else{
                    requestPermission();
                }
            }
        }
    

    convertToPdf() 方法:

      private void convertToPdf(){
            PdfGenerator pdfGenerator = new PdfGenerator(LayoutToPdfActivity.this);
          // llLayoutToPdfMain is variable of that view which convert to PDF
            Bitmap bitmap = pdfGenerator.getViewScreenShot(llLayoutToPdfMain);
            pdfGenerator.saveImageToPDF(llLayoutToPdfMain, bitmap);
        }
    

    PdfGenerator 类:

    public class PdfGenerator {
        private static String TAG= PdfGenerator.class.getSimpleName();
        private File mFile;
        private Context mContext;
    
        public PdfGenerator(Context context) {
            this.mContext = context;
        }
    
        /*save image to pdf*/
        public void saveImageToPDF(View title, Bitmap bitmap) {
            File path = Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOCUMENTS);
            if(!path.exists()) {
                path.mkdirs();
            }
            try {
                mFile = new File(path + "/", System.currentTimeMillis() + ".pdf");
                if (!mFile.exists()) {
                    int height = bitmap.getHeight();
                    PdfDocument document = new PdfDocument();
                    PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(bitmap.getWidth(), height, 1).create();
                    PdfDocument.Page page = document.startPage(pageInfo);
                    Canvas canvas = page.getCanvas();
                    title.draw(canvas);
                    canvas.drawBitmap(bitmap, null, new Rect(0, bitmap.getHeight(), bitmap.getWidth(), bitmap.getHeight()), null);
                    document.finishPage(page);
                    try {
                        mFile.createNewFile();
                        OutputStream out = new FileOutputStream(mFile);
                        document.writeTo(out);
                        document.close();
                        out.close();
                        Log.e(TAG,"Pdf Saved at:"+mFile.getAbsolutePath());
                        Toast.makeText(mContext,"Pdf Saved at:"+mFile.getAbsolutePath(),Toast.LENGTH_SHORT).show();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        /*method for generating bitmap from LinearLayout, RelativeLayout etc.*/
        public Bitmap getViewScreenShot(View view)
        {
            view.setDrawingCacheEnabled(true);
            view.buildDrawingCache();
            Bitmap bm = view.getDrawingCache();
            return bm;
        }
    
        
        /*method for generating bitmap from ScrollView, NestedScrollView*/
        public Bitmap getScrollViewScreenShot(ScrollView nestedScrollView)
        {
    
            int totalHeight = nestedScrollView.getChildAt(0).getHeight();
            int totalWidth = nestedScrollView.getChildAt(0).getWidth();
            return getBitmapFromView(nestedScrollView,totalHeight,totalWidth);
        }
    
    
        public Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
    
            Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(returnedBitmap);
            Drawable bgDrawable = view.getBackground();
            if (bgDrawable != null)
                bgDrawable.draw(canvas);
            else
                canvas.drawColor(Color.WHITE);
            view.draw(canvas);
            return returnedBitmap;
        }
    }
    

    编辑 请按照以下xml代码sn-p进行布局设计:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:gravity="center"
        tools:context=".views.activities.LayoutToPdfActivity">
        <androidx.core.widget.NestedScrollView
            android:id="@+id/nestedLayoutToPdf"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_above="@+id/btnGeneratePdf">
            <LinearLayout
                android:id="@+id/llLayoutToPdfMain"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical"
                android:gravity="center">
                <TableLayout
                    android:id="@+id/tableLayout1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >
                </TableLayout>
                <TableLayout
                    android:id="@+id/tableLayout2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" >
                </TableLayout>
            </LinearLayout>
        </androidx.core.widget.NestedScrollView>
        <Button
            android:id="@+id/btnGeneratePdf"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Generate Pdf"
            android:layout_margin="20dp"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"/>
    </RelativeLayout> 
    

    -> convertToPdf() 方法的变化

    private void convertToPdf() {
            PdfGenerator pdfGenerator = new PdfGenerator(LayoutToPdfActivity.this);
            Bitmap bitmap = pdfGenerator.getScrollViewScreenShot(nestedLayoutToPdf);
            pdfGenerator.saveImageToPDF(llLayoutToPdfMain, bitmap);
        }
    

    注意 - 请根据您的要求更改布局,并在 PdfGenerator 类下的 getScrollViewScreenShot() 方法中将参数类型更改为 NestedScrollView。

    要在 tableview 中动态添加行,请查看link

    【讨论】:

    • 哇,非常感谢!但是您知道如何包含一个表并且数据来自 firebase 数据库吗?非常感谢您的回复!
    猜你喜欢
    • 2013-05-04
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-22
    • 2020-03-24
    • 2013-04-17
    • 1970-01-01
    相关资源
    最近更新 更多