Create PDF and print PDF with WIFI printer in Android Java.
Today we will learn how to create a pdf file and after creating a pdf file we will be able to print this pdf using a wifi printer.
First of all, we need to add dependency in the build.Gradle(:app)file.
implementation 'com.itextpdf:itextg:5.5.10'
implementation 'com.karumi:dexter:6.2.3'
Now we need to add uses permission and the provider in the manifest file.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidpdfprint">
<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.AndroidPDFPrint">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:authorities="com.example.androidpdfprint.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
android:name="androidx.core.content.FileProvider">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
</application>
</manifest>
In the res folder, we need to add an XML directory and after creating the XML directory create an XML file.
provider_path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="exteranl_files"
path="."/>
</paths>
Now we will design our UI part in the main activity.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">
<Button
android:id="@+id/btn_create_pdf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/roboto"
android:text="Create PDF"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Now we will code for the MainActivity.
MainActivity.java
package com.example.androidpdfprint;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.content.Context;
import android.os.Bundle;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfDocument;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.LineSeparator;
import com.itextpdf.text.pdf.draw.VerticalPositionMark;
import com.karumi.dexter.Dexter;
import com.karumi.dexter.PermissionToken;
import com.karumi.dexter.listener.PermissionDeniedResponse;
import com.karumi.dexter.listener.PermissionGrantedResponse;
import com.karumi.dexter.listener.PermissionRequest;
import com.karumi.dexter.listener.single.PermissionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
public class MainActivity extends AppCompatActivity {
Button btn_create_pdf;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_create_pdf = (Button)findViewById(R.id.btn_create_pdf);
Dexter.withActivity(this)
.withPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.withListener(new PermissionListener() {
@Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
btn_create_pdf.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createPDFFile(Comman.getAppPath(MainActivity.this)+"test_pdf.pdf");
}
});
}
@Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
}
@Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
}
})
.check();
}
private void createPDFFile(String path) {
String date = new SimpleDateFormat("dd-MM-yyyy", Locale.getDefault()).format(new Date());
if(new File(path).exists())
new File(path).delete();
try {
Document document = new Document();
//Save
PdfWriter.getInstance(document,new FileOutputStream(path));
//open to write
document.open();
//Settings
document.setPageSize(PageSize.A4);
document.addCreationDate();
document.addAuthor("Harshita");
document.addCreator("Harshita Bambure");
//Font Settings
BaseColor colorAccent = new BaseColor(0,153,204,255);
float fontSizeHeader = 20.0f;
float fontSizeBody = 16.0f;
float valueFontSize = 26.0f;
//Custom font
BaseFont fontName = BaseFont.createFont("res/font/roboto.ttf","UTF-8",BaseFont.EMBEDDED);
//create title of document
Font titleFont = new Font(fontName,20.0f,Font.NORMAL,BaseColor.BLACK);
addNewItem(document,"Order Deatils", Element.ALIGN_CENTER,titleFont);
// Add more
Font orderNumberFont = new Font(fontName,fontSizeHeader,Font.NORMAL,colorAccent);
addNewItem(document,"order number",Element.ALIGN_LEFT,orderNumberFont);
Font orderNumberValueFont = new Font(fontName,valueFontSize,Font.NORMAL,BaseColor.BLACK);
addNewItem(document,"#525263",Element.ALIGN_LEFT,orderNumberValueFont);
addLineSeperator(document);
addNewItem(document,"Order Date",Element.ALIGN_LEFT,orderNumberFont);
addNewItem(document,date,Element.ALIGN_LEFT,orderNumberValueFont);
addLineSeperator(document);
addNewItem(document,"Account name",Element.ALIGN_LEFT,orderNumberFont);
addNewItem(document,"Harshita",Element.ALIGN_LEFT,orderNumberValueFont);
addLineSeperator(document);
//Add product order detail
addLineSpace(document);
addNewItem(document,"Product details",Element.ALIGN_CENTER,titleFont);
addLineSeperator(document);
//item 1
addNewItemWithLeftAndRight(document,"Burger","(1.0%)",titleFont,orderNumberValueFont);
addNewItemWithLeftAndRight(document,"20","1200.0",titleFont,orderNumberValueFont);
addLineSeperator(document);
//item 2
addNewItemWithLeftAndRight(document,"Pizza","(0.0%)",titleFont,orderNumberValueFont);
addNewItemWithLeftAndRight(document,"12","1520.0",titleFont,orderNumberValueFont);
addLineSeperator(document);
//item 3
addNewItemWithLeftAndRight(document,"Sandwich","(0.0%)",titleFont,orderNumberValueFont);
addNewItemWithLeftAndRight(document,"10","1000.0",titleFont,orderNumberValueFont);
addLineSeperator(document);
//Total
addLineSpace(document);
addLineSpace(document);
addNewItemWithLeftAndRight(document,"total","8500",titleFont,orderNumberValueFont);
document.close();
Toast.makeText(this,"Sucess",Toast.LENGTH_SHORT).show();
printPDF();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void addNewItem(Document document, String text, int align, Font font) throws DocumentException {
Chunk chunk = new Chunk(text,font);
Paragraph paragraph = new Paragraph(chunk);
paragraph.setAlignment(align);
document.add(paragraph);
}
private void addNewItemWithLeftAndRight(Document document, String textLeft, String textRight, Font textLeftFont,Font textRightFont) throws DocumentException {
Chunk chunkTextLeft = new Chunk(textLeft,textLeftFont);
Chunk chunkTextRight = new Chunk(textRight,textRightFont);
Paragraph p = new Paragraph(chunkTextLeft);
p.add(new Chunk(new VerticalPositionMark()));
p.add(chunkTextRight);
document.add(p);
}
private void addLineSeperator(Document document)throws DocumentException {
LineSeparator lineSeparator = new LineSeparator();
lineSeparator.setLineColor(new BaseColor(0,0,0,68));
addLineSpace(document);
document.add(new Chunk(lineSeparator));
}
private void addLineSpace(Document document) throws DocumentException {
document.add(new Paragraph(""));
}
private void printPDF(){
PrintManager printManager = (PrintManager)getSystemService(Context.PRINT_SERVICE);
try {
PrintDocumentAdapter printDocumentAdapter = new PdfDocumentAdapter(MainActivity.this,Comman.getAppPath(MainActivity.this)+"test_pdf.pdf");
printManager.print("Document",printDocumentAdapter,new PrintAttributes.Builder().build());
}catch (Exception ex){
Log.e("Harshita",""+ex.getMessage());
Toast.makeText(MainActivity.this, "Can't read pdf file", Toast.LENGTH_SHORT).show();
}
}
}
PdfDocumentAdapter.java
package com.example.androidpdfprint;
import android.content.Context;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.ParcelFileDescriptor;
import android.print.PageRange;
import android.print.PrintAttributes;
import android.print.PrintDocumentAdapter;
import android.print.PrintDocumentInfo;
import android.printservice.PrintDocument;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class PdfDocumentAdapter extends PrintDocumentAdapter {
Context context;
String path;
public PdfDocumentAdapter(Context context,String path){
this.context = context;
this.path = path;
}
@Override
public void onLayout(PrintAttributes oldAttributes, PrintAttributes printAttributes1, CancellationSignal cancellationSignal, LayoutResultCallback layoutResultCallback, Bundle extras) {
if (cancellationSignal.isCanceled())
layoutResultCallback.onLayoutCancelled();
else
{
PrintDocumentInfo.Builder builder = new PrintDocumentInfo.Builder("file name");
builder.setContentType(PrintDocumentInfo.CONTENT_TYPE_DOCUMENT)
.setPageCount(PrintDocumentInfo.PAGE_COUNT_UNKNOWN)
.build();
layoutResultCallback.onLayoutFinished(builder.build(),!printAttributes1.equals(printAttributes1));
}
}
@Override
public void onWrite(PageRange[] pages, ParcelFileDescriptor parcelFileDescriptor, CancellationSignal cancellationSignal, WriteResultCallback writeResultCallback) {
InputStream in = null;
OutputStream out = null;
try{
File file = new File(path);
in = new FileInputStream(file);
out = new FileOutputStream(parcelFileDescriptor.getFileDescriptor());
byte[]buff = new byte[16384];
int size;
while ((size = in.read(buff)) >= 0 && !cancellationSignal.isCanceled()){
out.write(buff,0,size);
}
if (cancellationSignal.isCanceled())
writeResultCallback.onWriteCancelled();
else{
writeResultCallback.onWriteFinished(new PageRange[]{PageRange.ALL_PAGES});
}
} catch (Exception e) {
writeResultCallback.onWriteFailed(e.getMessage());
Log.e("Harshita",e.getMessage());
e.printStackTrace();
}
finally {
try
{
in.close();
out.close();
}catch (IOException ex){
Log.e("Harshita", ""+ex.getMessage());
}
}
}
}
Comman.java
package com.example.androidpdfprint;
import android.content.Context;
import java.io.File;
public class Comman {
public static String getAppPath(Context context){
//File dir = new File(android.os.Environment.getExternalStorageDirectory()
File dir = new File(context.getFilesDir()
+ File.separator
+context.getResources().getString(R.string.app_name)
+ File.separator
);
if (!dir.exists())
dir.mkdir();
return dir.getPath() + File.separator;
}
}
Here is the source code.
Thank you for reading.
Happy Coding!!.