Video Demo:
Now we can use PdfDocument to generate the pdf file. But PdfDocument only works in 21 or above api level. In this tutorial I have created the pdf file with image and text. Download source code from here.
AndroidManifest.xml:
package="com.deepshikha.generatepdf">
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
activity_main.xml:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:orientation="vertical">
MainActivity.java:
package com.deepshikha.generatepdf;
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.pdf.PdfDocument;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
Button btn_generate;
TextView tv_link;
ImageView iv_image;
LinearLayout ll_pdflayout;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
Bitmap bitmap;
ProgressDialog progressDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
fn_permission();
listener();
}
private void init(){
btn_generate = (Button)findViewById(R.id.btn_generate);
tv_link = (TextView)findViewById(R.id.tv_link);
iv_image = (ImageView) findViewById(R.id.iv_image);
ll_pdflayout = (LinearLayout) findViewById(R.id.ll_pdflayout);
}
private void listener(){
btn_generate.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_generate:
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), PDFViewActivity.class);
startActivity(intent);
} else {
if (boolean_permission) {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage("Please wait");
bitmap = loadBitmapFromView(ll_pdflayout, ll_pdflayout.getWidth(), ll_pdflayout.getHeight());
createPdf();
// saveBitmap(bitmap);
} else {
}
createPdf();
break;
}
}
}
private void createPdf(){
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics displaymetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
float hight = displaymetrics.heightPixels ;
float width = displaymetrics.widthPixels ;
int convertHighet = (int) hight, convertWidth = (int) width;
// Resources mResources = getResources();
// Bitmap bitmap = BitmapFactory.decodeResource(mResources, R.drawable.screenshot);
PdfDocument document = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(convertWidth, convertHighet, 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
Canvas canvas = page.getCanvas();
Paint paint = new Paint();
canvas.drawPaint(paint);
bitmap = Bitmap.createScaledBitmap(bitmap, convertWidth, convertHighet, true);
paint.setColor(Color.BLUE);
canvas.drawBitmap(bitmap, 0, 0 , null);
document.finishPage(page);
// write the document content
String targetPdf = "/sdcard/test.pdf";
File filePath = new File(targetPdf);
try {
document.writeTo(new FileOutputStream(filePath));
btn_generate.setText("Check PDF");
boolean_save=true;
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "Something wrong: " + e.toString(), Toast.LENGTH_LONG).show();
}
// close the document
document.close();
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)||
(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.READ_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
activity_pdfview.xml:
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
android:id="@+id/pdfview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp">
PDFViewActivity.java:
package com.deepshikha.generatepdf;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import com.github.barteksc.pdfviewer.PDFView;
import com.github.barteksc.pdfviewer.listener.OnLoadCompleteListener;
import com.github.barteksc.pdfviewer.listener.OnPageChangeListener;
import com.github.barteksc.pdfviewer.scroll.DefaultScrollHandle;
import com.shockwave.pdfium.PdfDocument;
import java.io.File;
import java.util.List;
/**
* Created by deepshikha on 29/5/17.
*/
public class PDFViewActivity extends AppCompatActivity implements OnPageChangeListener,OnLoadCompleteListener {
PDFView pdfView;
Integer pageNumber = 0;
String pdfFileName;
String TAG="PDFViewActivity";
int position=-1;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pdfview);
init();
}
private void init(){
pdfView= (PDFView)findViewById(R.id.pdfview);
position = getIntent().getIntExtra("position",-1);
displayFromSdcard();
}
private void displayFromSdcard() {
pdfFileName ="/sdcard/test.pdf";
File file = new File(pdfFileName);
Log.e("File path",file.getAbsolutePath());
pdfView.fromFile(file)
.defaultPage(pageNumber)
.enableSwipe(true)
.swipeHorizontal(false)
.onPageChange(this)
.enableAnnotationRendering(true)
.onLoad(this)
.scrollHandle(new DefaultScrollHandle(this))
.load();
}
@Override
public void onPageChanged(int page, int pageCount) {
pageNumber = page;
setTitle(String.format("%s %s / %s", pdfFileName, page + 1, pageCount));
}
@Override
public void loadComplete(int nbPages) {
PdfDocument.Meta meta = pdfView.getDocumentMeta();
printBookmarksTree(pdfView.getTableOfContents(), "-");
}
public void printBookmarksTree(List tree, String sep) {
for (PdfDocument.Bookmark b : tree) {
Log.e(TAG, String.format("%s %s, p %d", sep, b.getTitle(), b.getPageIdx()));
if (b.hasChildren()) {
printBookmarksTree(b.getChildren(), sep + "-");
}
}
}
}
Hi, is the generate button functionality supposed to take a snapshot of the entire screen (even if it is a scrolling view of more than one screen) and display as a congested single view on the PDF view display?
ReplyDeletethat's whats happening when I download the sourcecode for this sample and run it. If it is a sigle screen, its fine, but if there are multiple screens, all of them are compressed within a single screen in the pdfviewer.
Could you please advise how to make this as is saved.
thanks
Hello,
DeleteYes it will take the screenshot of entire screen and then create the pdf file. But if you want to create the multiple pages with following code:
PdfDocument document = new PdfDocument();
PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(convertWidth, convertHighet, 1).create();
Thanks!
This comment has been removed by the author.
DeleteCan you please share the code for scrollview and multiple pdf pages as i am unable to do this with this code
Deletesame doubt i have
DeleteThis comment has been removed by the author.
ReplyDeleteHey can u please share the code for printing the entire listview in android and generate a pdf of it
Deleteits working with some error in logs
ReplyDeletehow to download the pdf page to sdcard?
ReplyDeletethank you very much you saved my life.... lots lots lots of thanks
ReplyDeletecopy past stackoverflow
ReplyDeletei want create pdf with specific xml layout and pass multiple data from Api. I m not getting the way , how can i make that with this code . Can you please Define me how can i do that.
ReplyDelete