Introduction:
In this article, we will learn how to convert any web url to pdf file in Android. To create PDF in Android, we will use iText Library. But here, we will not use any third party libraries like iText Library.
iText Library:
This library is awesome and very useful. But the iText Community licensed this library with AGPL license. So, we need to license our own application under AGPL license.
Reference Link: http://developers.itextpdf.com/But google provided print API for Android to print any content directly from mobile app. We can use same Print API for generating and saving the pdf file. Without any introduction, we will skip into the coding part.
Reference Link: https://developer.android.com/training/printing/
Coding Part
I have detailed the article in the following sections.- Creating a new project with Empty activity.
- Setting up the project with Print Adapter Extension.
- Implementation of URL to PDF file generation.
Step 1: Creating New Project with Empty Activity.
- Creating New Project with Android Studio Open Android Studio and Select Create new project.
- Name the project as your wish and select your activity template.
- Click “finish” button to create new project in Android Studio.
Step 2: Setting up the project with Print Adapter Extension
- To create pdf file, we need to use “PrintDocumentAdapter.LayoutResultCallback” and it cannot be used by any class.
- So, we need to create a class with package name as “android.print” and we will named the class as “PdfPrint.java”
- Then paste the following code with callback interface.
@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); } }
Step 3: Implementation of URL to PDF file generation
In this part, we will learn how to use the Printer Extension created in the last step and How to create a PDF file.
- Open your activity_main.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>
- Then 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());
- Then create a pdf print adapter with print attributes what we need
Here, I have used default page size as “A4”. You can change as per your 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();
- Then call your extension method with Callback as shown below
The PdfPrint.Callback will return success or failure based on the extension method we created.new PdfPrint(printAttributes).print( printAdapter, file, fileName, new PdfPrint.CallbackPrint() { @Override public void onSuccess(String path) { } @Override public void onFailure(Exception ex) { } });
Full code of MainActivity:
Here you can find the full code of the MainActivity.java for generating 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);
}
}
Follow Us
Were this world an endless plain, and by sailing eastward we could for ever reach new distances