Introduction
In this article, we will learn how to convert a Web URL to a pdf file in Android. To create a PDF in Android, we usually use a third party library but here we will not use any third-party libraries.
iText Library
This library is awesome and very useful. But the iText Community licensed this library with the AGPL license. So, we need to license our own application under the AGPL license.
Reference Link - http://developers.itextpdf.com/
But Google provides a print API for Android to print any content directly from a mobile app. We can use the same Print API for generating and saving a web page content to a pdf file.
Reference Link - https://developer.android.com/training/printing/
Coding Part
I have detailed this article into the following 3 steps.
- Step 1: Creating a New Project with Empty Activity.
- Step 2: Setting up the project with Print Adapter Extension.
- Step 3: Implementation of URL to PDF file generation.
Creating a New Project with Android Studio
- Open Android Studio and select Create a new project.
- Name the project as per your wish and select your activity template.
- Click “Finish” button to create a new project in Android Studio.
Setting up the project with Print Adapter Extension
To create a pdf file, we need to use “PrintDocumentAdapter.LayoutResultCallback” and it cannot be used by any class.
Create a class with the package name “android.print” and the class name “PdfPrint.java”.
Paste the following code with a callback interface.
- package android.print;
-
- import android.os.Build;
- import android.os.CancellationSignal;
- import android.os.ParcelFileDescriptor;
- import android.support.annotation.RequiresApi;
- import android.util.Log;
-
- import java.io.File;
-
- @SuppressWarnings("ALL")
- public class PdfPrint {
- private static final String TAG = PdfPrint.class.getSimpleName();
- private final PrintAttributes printAttributes;
-
- public PdfPrint(PrintAttributes printAttributes) {
- this.printAttributes = printAttributes;
- }
-
- @RequiresApi(api = Build.VERSION_CODES.KITKAT)
- public void print(final PrintDocumentAdapter printAdapter, final File path, final String fileName,
- final CallbackPrint callback) {
- printAdapter.onLayout(null, printAttributes, null,
- new PrintDocumentAdapter.LayoutResultCallback() {
- @Override
- public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
- printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName),
- new CancellationSignal(), new PrintDocumentAdapter.WriteResultCallback() {
- @Override
- public void onWriteFinished(PageRange[] pages) {
- super.onWriteFinished(pages);
- if (pages.length > 0) {
- File file = new File(path, fileName);
- String path = file.getAbsolutePath();
- callback.onSuccess(path);
- } else {
- callback.onFailure(new Exception("Pages length not found"));
- }
-
- }
- });
- }
- }, null);
- }
-
- private ParcelFileDescriptor getOutputFile(File path, String fileName) {
- if (!path.exists()) {
- path.mkdirs();
- }
- File file = new File(path, fileName);
- try {
- file.createNewFile();
- return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_WRITE);
- } catch (Exception e) {
- Log.e(TAG, "Failed to open ParcelFileDescriptor", e);
- }
- return null;
- }
- public interface CallbackPrint {
- void onSuccess(String path);
- void onFailure(Exception ex);
- }
- }
Implementation of URL to PDF file generation
In this part, we will learn how to use the Printer Extension created in the last step to create a PDF file.
- Open your xml file and paste the following code.
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.androimads.androidpdfmaker.MainActivity">
-
- <WebView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:id="@+id/webView"
- android:layout_above="@id/textView"/>
-
- <TextView
- android:visibility="gone"
- android:background="@color/colorBackground"
- android:padding="2dp"
- android:text="Saving..."
- android:gravity="center"
- android:textColor="#FFFFFF"
- android:layout_alignParentBottom="true"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:id="@+id/textView"/>
-
- </RelativeLayout>
- Open your Activity file, in my case “MainActivity.java” and initialize “WebView” as shown below.
- webView = findViewById(R.id.webView);
- webView.loadUrl("https://www.androidmads.info/");
- webView.setWebViewClient(new WebViewClient());
- Create a pdf print adapter with print attributes what we need.
- String fileName = String.format("%s.pdf", new SimpleDateFormat("dd_MM_yyyyHH_mm_ss", Locale.US).format(new Date()));
- final PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(fileName);
- PrintAttributes printAttributes = new PrintAttributes.Builder()
- .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
- .setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600))
- .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
- .build();
Here, I have used a default page size as “A4”.
- Call your extension method with the callback as shown below.
- new PdfPrint(printAttributes).print(
- printAdapter,
- file,
- fileName,
- new PdfPrint.CallbackPrint() {
- @Override
- public void onSuccess(String path) {
- }
- @Override
- public void onFailure(Exception ex) {
- }
- });
The PdfPrint.Callback will return success or failure based on the extension method we created.
Full code of MainActivity
The following listing is the full code of the MainActivity.java for generating a pdf file.
- @TargetApi(Build.VERSION_CODES.LOLLIPOP)
- public class MainActivity extends AppCompatActivity {
-
- private WebView webView;
- private TextView textView;
- private int PERMISSION_REQUEST = 0;
- private boolean allowSave = true;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- textView = findViewById(R.id.textView);
- webView = findViewById(R.id.webView);
- webView.loadUrl("https://www.androidmads.info/");
- webView.setWebViewClient(new WebViewClient());
- }
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- getMenuInflater().inflate(R.menu.main, menu);
- return true;
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if (item.getItemId() == R.id.save) {
- savePdf();
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-
- private void savePdf() {
- if(!allowSave)
- return;
- allowSave = false;
- textView.setVisibility(View.VISIBLE);
- if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
- == PERMISSION_GRANTED) {
- String fileName = String.format("%s.pdf", new SimpleDateFormat("dd_MM_yyyyHH_mm_ss", Locale.US).format(new Date()));
- final PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(fileName);
- PrintAttributes printAttributes = new PrintAttributes.Builder()
- .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
- .setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600))
- .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
- .build();
- final File file = Environment.getExternalStorageDirectory();
- new PdfPrint(printAttributes).print(
- printAdapter,
- file,
- fileName,
- new PdfPrint.CallbackPrint() {
- @Override
- public void onSuccess(String path) {
- textView.setVisibility(View.GONE);
- allowSave = true;
- Toast.makeText(getApplicationContext(),
- String.format("Your file is saved in %s", path),
- Toast.LENGTH_LONG).show();
- }
-
- @Override
- public void onFailure(Exception ex) {
- textView.setVisibility(View.GONE);
- allowSave = true;
- Toast.makeText(getApplicationContext(),
- String.format("Exception while saving the file and the exception is %s", ex.getMessage()),
- Toast.LENGTH_LONG).show();
- }
- });
- } else {
- ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST);
- }
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- if (requestCode == PERMISSION_REQUEST) {
- if (grantResults[Arrays.asList(permissions).indexOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)] == PERMISSION_GRANTED) {
- savePdf();
- }
- }
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- }
- }
Reference
- https://developer.android.com/training/printing/.
Download
You can download the same code from
GitHub.
If you like this article, please like and share the article and start the repo in
GitHub.
Summary
In this article, we learned about How To Convert Web Link To PDF Without Using iText Library In Android.