如何将xml布局转为PDF报告?

问题描述 投票:0回答:2

enter image description here我已经在android studio中用XML创建了一个报告布局。单击布局上的“生成”按钮后,我需要将布局转换为 PDF 格式。有没有什么可能性可以让它成为可能?预先感谢您!

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

android-studio android-layout pdf button
2个回答
0
投票

用于生成 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 代码片段进行布局设计:

<?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。

要在表格视图中动态添加行,请检查此链接


0
投票

int TotalHeight =nestedScrollView.getChildAt(0).getHeight(); int TotalWidth =nestedScrollView.getChildAt(0).getWidth();

我在您的代码中遇到错误: 进程:com.example.pdfmaker,PID:7400 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.view.View android.widget.ScrollView.getChildAt(int)”

© www.soinside.com 2019 - 2024. All rights reserved.