Example of Generating a PDF File
Below is the sample GIF in which we will get to know what we are going to build in this article. Note that this application is built using Java language. In this project, we are going to display a simple button. After clicking the button our PDF file will be generated and we can see this PDF file saved in our files.

Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file.
- XML
Step 3: Add permission for reading and writing in the External Storage
Navigate to the app > AndroifManifest.xml file and add the below permissions to it.
- XML
Step 4: Working with the MainActivity.java file
Go to the MainActivity.java file and refer to the following code. Below is the code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
- Java
Custom Design Create code PDF
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.example.meyepro.TeacherDashBoard.CHR; |
1234567891011121314151617181920212223 package com.example.meyepro.DirectorDashBoard.Home;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.pdf.PdfDocument;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.os.Environment;
import android.provider.Settings;
import android.text.Layout;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupMenu;
import android.widget.Toast;
import com.example.meyepro.DirectorDashBoard.Adapter.DirectorHomeAdapter;
import com.example.meyepro.DirectorDashBoard.Adapter.DirectorHomeDataTableAdapter;
import com.example.meyepro.DirectorDashBoard.Model.ScheduleDetailsAndCHR;
import com.example.meyepro.R;
import com.example.meyepro.api.Api;
import com.example.meyepro.databinding.FragmentDirectorDataTableBinding;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.scalars.ScalarsConverterFactory;
public class DirectorDataTableFragment extends Fragment {
FragmentDirectorDataTableBinding binding;
DirectorHomeDataTableAdapter adapter;
int pageHeight = 1120;
int pagewidth = 900;
// creating a bitmap variable
// for storing our images
// constant code for runtime permissions
private static final int PERMISSION_REQUEST_CODE = 200;
ArrayList<ScheduleDetailsAndCHR> scheduleDetailsAndCHRS=new ArrayList<>();
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
binding= FragmentDirectorDataTableBinding.inflate(getLayoutInflater());
//code start
binding.btnGeneratePDF.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (checkPermission()) {
// Toast.makeText(getContext(), "Permission Granted", Toast.LENGTH_SHORT).show();
} else {
requestPermission();
}
// calling method to
// generate our PDF file.
// Generate the PDF
binding.btnGeneratePDF.setVisibility(View.INVISIBLE);
// PdfGenerator pdfGenerator= new PdfGenerator();
// pdfGenerator.generatePdf(TeacherSelectTimTableCHRActivity.this, binding.getRoot(), "TeacherCHR.pdf");
generatePDF();
// // Generate the PDF
// PdfGeneratorWithText.generatePdf(getApplication(), binding.getRoot(), "kk.pdf");
//
// // Copy the text to the clipboard
// String text = getTextFromView(binding.txtDate);
// PdfGeneratorWithText.copyTextToClipboard(getApplicationContext(), text);
binding.btnGeneratePDF.setVisibility(View.VISIBLE);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Api.BASE_URL)
.addConverterFactory(ScalarsConverterFactory.create())
.build();
Api api = retrofit.create(Api.class);
api.get_all_teacher_chr().enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
if(response.isSuccessful()){
scheduleDetailsAndCHRS.clear();
scheduleDetailsAndCHRS.addAll(new Gson().fromJson(response.body(),new TypeToken<ArrayList<ScheduleDetailsAndCHR>>(){}.getType()));
Toast.makeText(getContext(), ""+scheduleDetailsAndCHRS.size(), Toast.LENGTH_SHORT).show();
adapter = new
DirectorHomeDataTableAdapter(scheduleDetailsAndCHRS, getActivity(),DirectorDataTableFragment.this);
LinearLayoutManager manager = new LinearLayoutManager(getActivity());
binding.RecycerviewDirectorDatatable.setLayoutManager(manager);
binding.RecycerviewDirectorDatatable.setHasFixedSize(true);
binding.RecycerviewDirectorDatatable.
setAdapter(adapter);
}
}
@Override
public void onFailure(Call<String> call, Throwable t) {
}
});
//code end
return binding.getRoot();
}
private void generatePDF() {
// initializing our variables.
// bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon_dvr_camera_setting);
// scaledbmp = Bitmap.createScaledBitmap(bmp, 140, 140, false);
// creating an object variable
// for our PDF document.
PdfDocument pdfDocument = new PdfDocument();
// two variables for paint "paint" is used
// for drawing shapes and we will use "title"
// for adding text in our PDF file.
Paint paint = new Paint();
Paint title = new Paint();
// we are adding page info to our PDF file
// in which we will be passing our pageWidth,
// pageHeight and number of pages and after that
// we are calling it to create our PDF.
PdfDocument.PageInfo mypageInfo = new PdfDocument.PageInfo.Builder(pagewidth, pageHeight, 1).create();
// below line is used for setting
// start page for our PDF file.
PdfDocument.Page myPage = pdfDocument.startPage(mypageInfo);
// creating a variable for canvas
// from our page of PDF.
Canvas canvas = myPage.getCanvas();
// Get the drawable from the ImageView
// BitmapDrawable bmpDrawable = (BitmapDrawable) binding.profileImageTeacher.getDrawable();
// Bitmap bmpImage = bmpDrawable.getBitmap();
// Calculate the desired resolution based on the zoom level
float zoomLevel = 2.0f; // Adjust the zoom level as needed
int desiredWidth = (int) (50* zoomLevel);
int desiredHeight = (int) (50 * zoomLevel);
//// Create a new bitmap with the desired resolution
// Bitmap highResBitmap = Bitmap.createScaledBitmap(bmpImage, desiredWidth, desiredHeight, true);
// paint.setAntiAlias(true);
// paint.setFilterBitmap(true);
// // Calculate the x coordinate to align the image to the right
// int x = pagewidth-140;
//// Draw the high-resolution bitmap onto the PDF canvas
// canvas.drawBitmap(highResBitmap, x, 20, paint);
// below line is used for adding typeface for
// our text which we will be adding in our PDF file.
title.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.NORMAL));
// below line is used for setting text size
// which we will be displaying in our PDF file.
title.setTextSize(15);
// below line is sued for setting color
// of our text inside our PDF file.
title.setColor(ContextCompat.getColor(getContext(), R.color.purple_200));
// below line is used to draw text in our PDF file.
// the first parameter is our text, second parameter
// is position from start, third parameter is position from top
// and then we are passing our variable of paint which is title.
title.setTypeface(Typeface.create(Typeface.DEFAULT,Typeface.BOLD));
title.setFlags(title.getFlags() | Paint.UNDERLINE_TEXT_FLAG);
// canvas.drawText(binding.txtViewTeacherName.getText().toString(), 209, 70, title);
// canvas.drawText("MEYE Pro", 209, 80, title);
// similarly we are creating another text and in this
// we are aligning this text to center of our PDF file.
title.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
title.setColor(ContextCompat.getColor(getContext(), R.color.purple_200));
title.setTextSize(15);
Paint linePaint = new Paint();
linePaint.setColor(getResources().getColor(R.color.blue_500)); // Set the desired color for the lines
linePaint.setStrokeWidth(1); // Set the desired width for the lines
float starttopX = 0; // Starting X coordinate for the lines
float startTopY = 10; // Starting Y coordinate for the lines
float endTopX = canvas.getWidth(); // Ending X coordinate for the lines
float endTopY = canvas.getHeight(); // Ending Y coordinate for the lines
canvas.drawLines(new float[]{starttopX, startTopY, endTopX, startTopY, starttopX, endTopY, endTopX, endTopY}, linePaint);
// Calculate the width for each column based on the page width and the number of columns
int columnCount = 8;
int columnWidth = pagewidth / columnCount;
Paint paintTxt= new Paint();
paintTxt.setTypeface(Typeface.defaultFromStyle(Typeface.NORMAL));
paintTxt.setTextSize(15);
int index=1;
// Toast.makeText(getContext(), "check", Toast.LENGTH_SHORT).show();
// Draw column headers
int x = 20;
canvas.drawText("St. No", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Teacher", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Course", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Date", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Sit", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Strand", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Mobile", x, 30*index, paintTxt);
x += columnWidth;
canvas.drawText("Status", x, 30*index, paintTxt);
float startX = 0; // Starting X coordinate for the lines
float startY = 40*index; // Starting Y coordinate for the lines
float endX = canvas.getWidth(); // Ending X coordinate for the lines
float endY = canvas.getHeight(); // Ending Y coordinate for the lines
canvas.drawLines(new float[]{startX, startY, endX, startY, startX, endY, endX, endY}, linePaint);
for (ScheduleDetailsAndCHR scheduleDetailsAndCHR:scheduleDetailsAndCHRS) {
++index;
x = 20;
// Draw each column with adjusted width
drawTextWithWrapping(canvas, (index-1)+"", (x+10), 30*index, columnWidth, paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas, scheduleDetailsAndCHR.getTeacherName(), x, 30*index, columnWidth, paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas, scheduleDetailsAndCHR.getCourseName(), x, 30*index, columnWidth, paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas, scheduleDetailsAndCHR.getDate(), x, 30*index, columnWidth, paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas,"0", (8+x), 30*index, columnWidth,paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas,"0", (20+x), 30*index, columnWidth,paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas,"0", (20+x), 30*index, columnWidth,paintTxt);
x += columnWidth;
drawTextWithWrapping(canvas,""+scheduleDetailsAndCHR.getStatus(), x, 30*index, columnWidth,paintTxt);
}
// after adding all attributes to our
// PDF file we will be finishing our page.
pdfDocument.finishPage(myPage);
// below line is used to set the name of
// our PDF file and its path.
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1) {
//
// }
// else
// {
//
//
// }
ContextWrapper cw = new ContextWrapper(getActivity().getApplicationContext());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
if (Environment.isExternalStorageManager()) {
// The app has been granted the MANAGE_EXTERNAL_STORAGE permission
File file = new File(String.valueOf(Environment.getExternalStorageDirectory()), "muzamil.pdf");
try {
// after creating a file name we will
// write our PDF file to that location.
pdfDocument.writeTo(new FileOutputStream(file));
// below line is to print toast message
// on completion of PDF generation.
Toast.makeText(getContext(), "PDF file generated successfully.", Toast.LENGTH_SHORT).show();
} catch (IOException e) {
// below line is used
// to handle error
e.printStackTrace();
// binding.txtCourse.setText(e.toString());
Toast.makeText(getContext(), ""+e.toString(), Toast.LENGTH_SHORT).show();
}
} else {
// The app has not been granted the MANAGE_EXTERNAL_STORAGE permission
// Request the permission from the user
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + getActivity().getPackageName()));
startActivity(intent);
}
}
// after storing our pdf to that
// location we are closing our PDF file.
pdfDocument.close();
}
// Helper method to draw text with wrapping
private void drawTextWithWrapping(Canvas canvas, String text, float x, float y, int width, Paint paint) {
CharSequence charSequence = text; // Convert String to CharSequence
TextPaint textPaint = new TextPaint();
textPaint.set(paint); // Copy attributes from the original Paint
StaticLayout staticLayout = new StaticLayout(charSequence, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
canvas.save();
canvas.translate(x, y);
staticLayout.draw(canvas);
canvas.restore();
}
private boolean checkPermission() {
// checking of permissions.
int permission1 = ContextCompat.checkSelfPermission(getContext(), WRITE_EXTERNAL_STORAGE);
int permission2 = ContextCompat.checkSelfPermission(getContext(), READ_EXTERNAL_STORAGE);
return permission1 == PackageManager.PERMISSION_GRANTED && permission2 == PackageManager.PERMISSION_GRANTED;
}
private void requestPermission() {
// requesting permissions if not provided.
ActivityCompat.requestPermissions(getActivity(), new String[]{WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0) {
// after requesting permissions we are showing
// users a toast message of permission granted.
boolean writeStorage = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean readStorage = grantResults[1] == PackageManager.PERMISSION_GRANTED;
if (writeStorage && readStorage) {
// Toast.makeText(this, "Permission Granted..", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getContext(), "Permission Denied.", Toast.LENGTH_SHORT).show();
}
}
}
}
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | package com.example.meyepro.DirectorDashBoard.Home; |