我已经在android studio中用XML创建了一个报告布局。单击布局上的“生成”按钮后,我需要将布局转换为 PDF 格式。有没有什么可能性可以让它成为可能?预先感谢您!
我想将布局中的数据转换为该表格中的 pdf
用于生成 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。
要在表格视图中动态添加行,请检查此链接
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)”