In this tutorial, we will discuss about generating PDF file.
There are many apps in the Play Store and other App Stores that provide the facility to create downloadable PDF files. These apps are like resume builder app which you can download PDF file. Others such as many apps that provide the facility to create downloadable PDF files. And you can save it on your device.
So friends, in this tutorial we will create PDF file and save it, it will open automatically when downloaded completed.
PDF file is very important when we want to allow user to download data as PDF format. However we are using downloadable PDF file using xml LinearLayout. We convert LinearLayout to PDF format file and then download easily.
What is the process to create and open a PDF file?
we will create pdf file through user data, means we will create one activity, in that activity we will use image and edit text, then send all data to other view activity and then pdf file as downloadable will generate. This is a simple process to generate LinearLayout in PDF file.
Let’s start the step by step process to generate PDF file.
How to generate downloadable PDF file
Step-1:
Create a new project, you can name it whatever you want.
Step-2:
Open AndroidManifest.xml and give storage permission to save PDF and open it.
App⇾manifests⇾AndroidManifest.xml and add below permission.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Full code of Androidmanifest.xml
Androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.layoutpdf">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LayoutPdf">
<activity android:name=".MainActivity2"></activity>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Step-3
Now open activity_main.xml and create UI design for edit text and ImageView data.
In this tutorial we will use ImageView, EditText and a button to send data from another Activity.
The code of activity_main.xml is given below.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
tools:context=".MainActivity">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher_round"
android:id="@+id/avatar"
android:layout_gravity="center"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/fname"
android:inputType="text"
android:hint="First Name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lname"
android:inputType="text"
android:hint="Last Name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/email"
android:inputType="textEmailAddress"
android:hint="Email Id"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/mobile"
android:inputType="number"
android:hint="Mobile No."/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/age"
android:inputType="number"
android:hint="AGe"/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/view"
android:text="view"/>
</LinearLayout>
Step-4
Go to MainActivity.java
In MainActivity.java file create some method and initialize id. We have already known about this.
Also, we use image so pick image from gallery and view it on image view. That topic is covered in “Send data from one activity to another“.
Then we will send all edit text and image view data to another activity.
The code of MainActivity.java is given below.
MainActivity.java
package com.example.layoutpdf;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
ImageView avatar;
EditText fname,lname,email,mobile,age;
Button view;
public static final int REQUEST_STORAGE=101;
String storagePermission[];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//create methods
findId();
storagePermission=new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
pickImage();
displayData();
}
private void displayData() {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MainActivity2.class);
intent.putExtra("avatar",imageViewToByte());
intent.putExtra("fname",fname.getText().toString());
intent.putExtra("lname",lname.getText().toString());
intent.putExtra("email",email.getText().toString());
intent.putExtra("mobile",mobile.getText().toString());
intent.putExtra("age",age.getText().toString());
startActivity(intent);
}
});
}
private byte[] imageViewToByte() {
Bitmap bitmap=((BitmapDrawable)avatar.getDrawable()).getBitmap();
ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG,80,byteArrayOutputStream);
byte[]bytes=byteArrayOutputStream.toByteArray();
return bytes;
}
private void pickImage() {
avatar.setOnClickListener(new View.OnClickListener() {
@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onClick(View v) {
int avatar=0;
if (avatar==0){
if (!checkStoragePermission()){
requestStoragePermission();
}else{
pickFromGallery();
}
}
}
});
}
private void pickFromGallery() {
Intent intent=new Intent();
intent.setType("image/jpg/png");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Pick Image"),101);
}
@RequiresApi(api = Build.VERSION_CODES.M)
private void requestStoragePermission() {
requestPermissions(storagePermission,REQUEST_STORAGE);
}
private boolean checkStoragePermission() {
boolean result= ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)==(PackageManager.PERMISSION_GRANTED);
return result;
}
private void findId() {
avatar=(ImageView)findViewById(R.id.avatar);
fname=(EditText)findViewById(R.id.fname);
lname=(EditText)findViewById(R.id.lname);
email=(EditText)findViewById(R.id.email);
mobile=(EditText)findViewById(R.id.mobile);
age=(EditText)findViewById(R.id.age);
view=(Button)findViewById(R.id.view);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==101&&resultCode==RESULT_OK){
Uri uri=data.getData();
Bitmap bitmap=null;
try {
bitmap= MediaStore.Images.Media.getBitmap(getContentResolver(),uri);
}catch (IOException e){
e.printStackTrace();
}
avatar.setImageBitmap(bitmap);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_STORAGE:{
if (grantResults.length>0){
boolean result=grantResults[0]==PackageManager.PERMISSION_GRANTED;
if (result){
pickFromGallery();
}else{
Toast.makeText(this, "Please enable storage permission", Toast.LENGTH_SHORT).show();
}
}
}
break;
}
}
}
Step-5
Create a new activity to view the data and create the PDF file.
App ⇾ right click on Package name ⇾ new ⇾ activity ⇾ empty activity.
Here named MainActivity2.
Open activity_main2.xml and create UI as per your view, here is a simple format to view data sequentially.
The code of activity_main2.xml is given below.
Activity_main2.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"
tools:context=".MainActivity2">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_baseline_save_alt_24"
android:id="@+id/save"
android:layout_centerHorizontal="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="20dp"
android:elevation="18dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
android:elevation="12dp"
android:orientation="vertical"
android:id="@+id/lld">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textSize="24dp"
android:gravity="center"
android:id="@+id/textview"
android:layout_marginTop="20dp"/>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@mipmap/ic_launcher_round"
android:layout_below="@+id/textview"
android:id="@+id/avatarview"
android:layout_centerHorizontal="true"/>
<TextView
android:textStyle="bold"
android:textSize="20dp"
android:layout_marginLeft="10dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/avatarview"
android:id="@+id/textview2"
android:text="First name"/>
<TextView
android:textSize="20dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/avatarview"
android:layout_toRightOf="@+id/textview2"
android:text="fist Name"
android:textAlignment="textStart"
android:id="@+id/fnameview"/>
<TextView
android:textStyle="bold"
android:textSize="20dp"
android:layout_marginLeft="10dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview2"
android:id="@+id/textview3"
android:text="Last name"/>
<TextView
android:textSize="20dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview2"
android:layout_toRightOf="@+id/textview2"
android:text="fist Name"
android:textAlignment="textStart"
android:id="@+id/lnameview"/>
<TextView
android:textStyle="bold"
android:textSize="20dp"
android:layout_marginLeft="10dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview3"
android:id="@+id/textview4"
android:text="Email Id"/>
<TextView
android:textSize="20dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview3"
android:layout_toRightOf="@+id/textview2"
android:text="fist Name"
android:textAlignment="textStart"
android:id="@+id/emailview"/>
<TextView
android:textStyle="bold"
android:textSize="20dp"
android:layout_marginLeft="10dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview4"
android:id="@+id/textview5"
android:text="Mobile"/>
<TextView
android:textSize="20dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview4"
android:layout_toRightOf="@+id/textview2"
android:text="fist Name"
android:textAlignment="textStart"
android:id="@+id/mobileview"/>
<TextView
android:textStyle="bold"
android:textSize="20dp"
android:layout_marginLeft="10dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview5"
android:id="@+id/textview6"
android:text="age"/>
<TextView
android:textSize="20dp"
android:layout_width="165dp"
android:layout_height="wrap_content"
android:layout_below="@+id/textview5"
android:layout_toRightOf="@+id/textview2"
android:text="Age"
android:textAlignment="textStart"
android:id="@+id/ageview"/>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
Step-6
Generate PDF file to view data and go to MainActivity2.java.
In MainActivity2.java file we will create some method similar to Mainactivity.java. And see at the data that we already know in the topic “Send data from one Activity to another” and also discussed “Convert Android LinearLayout to PDF“.
The code of MainActivity2.java is given below.
package com.example.layoutpdf;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.function.BiFunction;
public class MainActivity2 extends AppCompatActivity {
ImageView avatarview;
TextView fnameview,lnameview,emailview,mobileview,ageview;
LinearLayout linearLayout;
ImageButton save;
Bitmap bitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
findId();
viewData();
savePdf();
}
private void savePdf() {
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("size",linearLayout.getWidth()+" "+linearLayout.getHeight());
bitmap=loadBitmapFromView(linearLayout,linearLayout.getWidth(),linearLayout.getHeight());
createPdf();
}
});
}
private void createPdf() {
DisplayMetrics displayMetrics=new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
float height=displayMetrics.heightPixels;
float width=displayMetrics.widthPixels;
int convertHeight=(int)height,
convertWidth=(int)width;
PdfDocument document=new PdfDocument();
PdfDocument.PageInfo pageInfo=new PdfDocument.PageInfo.Builder(convertWidth,convertHeight,1).create();
PdfDocument.Page page=document.startPage(pageInfo);
Canvas canvas=page.getCanvas();
Paint paint=new Paint();
canvas.drawPaint(paint);
bitmap=Bitmap.createScaledBitmap(bitmap,convertWidth,convertHeight,true);
canvas.drawBitmap(bitmap,0,0,null);
document.finishPage(page);
//write document content
String targetPdf="sdcard/page.pdf";
File filepath=new File(targetPdf);
try {
document.writeTo(new FileOutputStream(filepath));
}catch (IOException e){
e.printStackTrace();
Toast.makeText(this, "something want wrong try again"+e.toString(), Toast.LENGTH_SHORT).show();
}
//close document
document.close();
Toast.makeText(this, "pdf created successfully", Toast.LENGTH_SHORT).show();
openPdf();
}
private void openPdf() {
File file=new File("/sdcard/page.pdf");
Intent intent=new Intent(Intent.ACTION_VIEW);
Uri uri=Uri.fromFile(file);
intent.setDataAndType(uri,"application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
startActivity(intent);
}catch (ActivityNotFoundException e){
Toast.makeText(this, "No application found for pdf reader", Toast.LENGTH_SHORT).show();
}
}
private Bitmap loadBitmapFromView(LinearLayout linearLayout, int width, int height) {
bitmap=Bitmap.createBitmap(width,height, Bitmap.Config.ARGB_8888);
Canvas canvas=new Canvas(bitmap);
linearLayout.draw(canvas);
return bitmap;
}
private void viewData() {
Intent intent=getIntent();
byte[]bytes=intent.getByteArrayExtra("avatar");
Bitmap bitmap= BitmapFactory.decodeByteArray(bytes,0,bytes.length);
avatarview.setImageBitmap(bitmap);
String fname=intent.getStringExtra("fname");
String lname=intent.getStringExtra("lname");
String email=intent.getStringExtra("email");
String mobile=intent.getStringExtra("mobile");
String age=intent.getStringExtra("age");
//set view
fnameview.setText(":-"+fname.toString());
lnameview.setText(":-"+lname.toString());
emailview.setText(":-"+email.toString());
mobileview.setText(":-"+mobile.toString());
ageview.setText(":-"+age.toString());
}
private void findId() {
avatarview=(ImageView)findViewById(R.id.avatarview);
fnameview=(TextView)findViewById(R.id.fnameview);
lnameview=(TextView)findViewById(R.id.lnameview);
emailview=(TextView)findViewById(R.id.emailview);
mobileview=(TextView)findViewById(R.id.mobileview);
ageview=(TextView)findViewById(R.id.ageview);
linearLayout=findViewById(R.id.lld);
save=findViewById(R.id.save);
}
}
Now run your project and see the output. As the output below shows.