├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── itextg-5.5.8.jar ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── casariego │ │ └── jorge │ │ └── createpdf │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── casariego │ │ │ └── jorge │ │ │ └── createpdf │ │ │ ├── MainActivity.java │ │ │ ├── Pdf1Activity.java │ │ │ └── Pdf2Activity.java │ └── res │ │ ├── layout │ │ ├── activity_main.xml │ │ ├── activity_pdf1.xml │ │ └── activity_pdf2.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── casariego │ └── jorge │ └── createpdf │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android-PDF-Creator 2 | This repository show how to create a PDF using iText library 3 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.2" 6 | 7 | defaultConfig { 8 | applicationId "casariego.jorge.createpdf" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(include: ['*.jar'], dir: 'libs') 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.2.1' 26 | compile files('libs/itextg-5.5.8.jar') 27 | } 28 | -------------------------------------------------------------------------------- /app/libs/itextg-5.5.8.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jorgecasariego/Android-PDF-Creator/e6cd8fb97ff8c1812e2f7a1d0cd573565f5634cb/app/libs/itextg-5.5.8.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Applications/Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/casariego/jorge/createpdf/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package casariego.jorge.createpdf; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/casariego/jorge/createpdf/MainActivity.java: -------------------------------------------------------------------------------- 1 | package casariego.jorge.createpdf; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 10 | 11 | 12 | private Button crearPdf1; 13 | private Button crearPdf2; 14 | 15 | @Override 16 | protected void onCreate(Bundle savedInstanceState) { 17 | super.onCreate(savedInstanceState); 18 | setContentView(R.layout.activity_main); 19 | 20 | crearPdf1 = (Button) findViewById(R.id.crear1); 21 | crearPdf1.setOnClickListener(this); 22 | 23 | crearPdf2 = (Button) findViewById(R.id.crear2); 24 | crearPdf2.setOnClickListener(this); 25 | } 26 | 27 | @Override 28 | public void onClick(View v) { 29 | Intent i = null; 30 | 31 | switch (v.getId()){ 32 | case R.id.crear1: 33 | i = new Intent(this, Pdf1Activity.class); 34 | break; 35 | case R.id.crear2: 36 | i = new Intent(this, Pdf2Activity.class); 37 | break; 38 | } 39 | 40 | startActivity(i); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/casariego/jorge/createpdf/Pdf1Activity.java: -------------------------------------------------------------------------------- 1 | package casariego.jorge.createpdf; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.pm.PackageManager; 6 | import android.os.Environment; 7 | import android.support.v4.app.ActivityCompat; 8 | import android.support.v4.content.ContextCompat; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.os.Bundle; 11 | import android.util.Log; 12 | import android.view.View; 13 | import android.widget.EditText; 14 | import android.widget.Toast; 15 | 16 | import com.itextpdf.text.Anchor; 17 | import com.itextpdf.text.BadElementException; 18 | import com.itextpdf.text.BaseColor; 19 | import com.itextpdf.text.Chapter; 20 | import com.itextpdf.text.Document; 21 | import com.itextpdf.text.DocumentException; 22 | import com.itextpdf.text.Element; 23 | import com.itextpdf.text.Font; 24 | import com.itextpdf.text.List; 25 | import com.itextpdf.text.ListItem; 26 | import com.itextpdf.text.Paragraph; 27 | import com.itextpdf.text.Phrase; 28 | import com.itextpdf.text.Section; 29 | import com.itextpdf.text.pdf.PdfPCell; 30 | import com.itextpdf.text.pdf.PdfPTable; 31 | import com.itextpdf.text.pdf.PdfWriter; 32 | 33 | import java.io.File; 34 | import java.io.FileNotFoundException; 35 | import java.io.FileOutputStream; 36 | import java.util.Date; 37 | 38 | public class Pdf1Activity extends AppCompatActivity { 39 | private static Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD); 40 | private static Font redFont = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.NORMAL, BaseColor.RED); 41 | private static Font subFont = new Font(Font.FontFamily.TIMES_ROMAN, 16, Font.BOLD); 42 | private static Font smallBold = new Font(Font.FontFamily.TIMES_ROMAN, 12, Font.BOLD); 43 | 44 | // Storage Permissions 45 | private static final int REQUEST_EXTERNAL_STORAGE = 1; 46 | 47 | private static String[] PERMISSIONS_STORAGE = { 48 | Manifest.permission.READ_EXTERNAL_STORAGE, 49 | Manifest.permission.WRITE_EXTERNAL_STORAGE 50 | }; 51 | 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | super.onCreate(savedInstanceState); 55 | setContentView(R.layout.activity_pdf1); 56 | 57 | verifyStoragePermissions(this); 58 | } 59 | 60 | /** 61 | * Checks if the app has permission to write to device storage 62 | * 63 | * If the app does not has permission then the user will be prompted to grant permissions 64 | * 65 | * @param activity 66 | */ 67 | public static void verifyStoragePermissions(Activity activity) { 68 | // Check if we have write permission 69 | if (ContextCompat.checkSelfPermission(activity, 70 | Manifest.permission.WRITE_EXTERNAL_STORAGE) 71 | != PackageManager.PERMISSION_GRANTED) { 72 | 73 | // Should we show an explanation? 74 | if (ActivityCompat.shouldShowRequestPermissionRationale(activity, 75 | Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 76 | 77 | // Show an expanation to the user *asynchronously* -- don't block 78 | // this thread waiting for the user's response! After the user 79 | // sees the explanation, try again to request the permission. 80 | 81 | } else { 82 | // No explanation needed, we can request the permission. 83 | ActivityCompat.requestPermissions(activity, 84 | PERMISSIONS_STORAGE, 85 | REQUEST_EXTERNAL_STORAGE); 86 | 87 | } 88 | 89 | 90 | } else { 91 | createPDF(); 92 | } 93 | } 94 | 95 | @Override 96 | public void onRequestPermissionsResult(int requestCode, 97 | String permissions[], int[] grantResults) { 98 | switch (requestCode) { 99 | case REQUEST_EXTERNAL_STORAGE: { 100 | // If request is cancelled, the result arrays are empty. 101 | if (grantResults.length > 0 102 | && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 103 | 104 | // permission was granted, yay! Do the 105 | // contacts-related task you need to do. 106 | createPDF(); 107 | 108 | } else { 109 | 110 | // permission denied, boo! Disable the 111 | // functionality that depends on this permission. 112 | 113 | Toast.makeText(Pdf1Activity.this, "No podemos escribir sin tener permiso", Toast.LENGTH_SHORT).show(); 114 | } 115 | return; 116 | } 117 | 118 | // other 'case' lines to check for other 119 | // permissions this app might request 120 | } 121 | } 122 | 123 | public static void createPDF(){ 124 | //create document object 125 | Document document=new Document(); 126 | 127 | //output file path 128 | String outpath= Environment.getExternalStorageDirectory()+"/theBestPdf/PDF1.pdf"; 129 | 130 | 131 | try { 132 | PdfWriter.getInstance(document, new FileOutputStream(outpath)); 133 | document.open(); 134 | addMetaData(document); 135 | addTitlePage(document); 136 | addContent(document); 137 | document.close(); 138 | 139 | } catch (FileNotFoundException e) { 140 | // TODO Auto-generated catch block 141 | e.printStackTrace(); 142 | } catch (DocumentException e) { 143 | // TODO Auto-generated catch block 144 | e.printStackTrace(); 145 | } 146 | } 147 | 148 | // iText allows to add metadata to the PDF which can be viewed in your Adobe 149 | // Reader 150 | // under File -> Properties 151 | private static void addMetaData(Document document) { 152 | document.addTitle("My first PDF"); 153 | document.addSubject("Using iText"); 154 | document.addKeywords("Java, PDF, iText"); 155 | document.addAuthor("Lars Vogel"); 156 | document.addCreator("Lars Vogel"); 157 | } 158 | 159 | private static void addTitlePage(Document document) 160 | throws DocumentException { 161 | Paragraph preface = new Paragraph(); 162 | // We add one empty line 163 | addEmptyLine(preface, 1); 164 | // Lets write a big header 165 | preface.add(new Paragraph("Title of the document", catFont)); 166 | 167 | addEmptyLine(preface, 1); 168 | // Will create: Report generated by: _name, _date 169 | preface.add(new Paragraph("Report generated by: " + System.getProperty("user.name") + ", " + new Date(), //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ 170 | smallBold)); 171 | addEmptyLine(preface, 3); 172 | preface.add(new Paragraph("This document describes something which is very important ", 173 | smallBold)); 174 | 175 | addEmptyLine(preface, 8); 176 | 177 | preface.add(new Paragraph("This document is a preliminary version and not subject to your license agreement or any other agreement with vogella.com ;-).", 178 | redFont)); 179 | 180 | document.add(preface); 181 | // Start a new page 182 | document.newPage(); 183 | } 184 | 185 | private static void addContent(Document document) throws DocumentException { 186 | Anchor anchor = new Anchor("First Chapter", catFont); 187 | anchor.setName("First Chapter"); 188 | 189 | // Second parameter is the number of the chapter 190 | Chapter catPart = new Chapter(new Paragraph(anchor), 1); 191 | 192 | Paragraph subPara = new Paragraph("Subcategory 1", subFont); 193 | Section subCatPart = catPart.addSection(subPara); 194 | subCatPart.add(new Paragraph("Hello")); 195 | 196 | subPara = new Paragraph("Subcategory 2", subFont); 197 | subCatPart = catPart.addSection(subPara); 198 | subCatPart.add(new Paragraph("Paragraph 1")); 199 | subCatPart.add(new Paragraph("Paragraph 2")); 200 | subCatPart.add(new Paragraph("Paragraph 3")); 201 | 202 | // add a list 203 | createList(subCatPart); 204 | Paragraph paragraph = new Paragraph(); 205 | addEmptyLine(paragraph, 5); 206 | subCatPart.add(paragraph); 207 | 208 | // add a table 209 | createTable(subCatPart); 210 | 211 | // now add all this to the document 212 | document.add(catPart); 213 | 214 | // Next section 215 | anchor = new Anchor("Second Chapter", catFont); 216 | anchor.setName("Second Chapter"); 217 | 218 | // Second parameter is the number of the chapter 219 | catPart = new Chapter(new Paragraph(anchor), 1); 220 | 221 | subPara = new Paragraph("Subcategory", subFont); 222 | subCatPart = catPart.addSection(subPara); 223 | subCatPart.add(new Paragraph("This is a very important message")); 224 | 225 | // now add all this to the document 226 | document.add(catPart); 227 | 228 | } 229 | 230 | private static void createTable(Section subCatPart) 231 | throws BadElementException { 232 | PdfPTable table = new PdfPTable(3); 233 | 234 | // t.setBorderColor(BaseColor.GRAY); 235 | // t.setPadding(4); 236 | // t.setSpacing(4); 237 | // t.setBorderWidth(1); 238 | 239 | PdfPCell c1 = new PdfPCell(new Phrase("Table Header 1")); 240 | c1.setHorizontalAlignment(Element.ALIGN_CENTER); 241 | table.addCell(c1); 242 | 243 | c1 = new PdfPCell(new Phrase("Table Header 2")); 244 | c1.setHorizontalAlignment(Element.ALIGN_CENTER); 245 | table.addCell(c1); 246 | 247 | c1 = new PdfPCell(new Phrase("Table Header 3")); 248 | c1.setHorizontalAlignment(Element.ALIGN_CENTER); 249 | table.addCell(c1); 250 | table.setHeaderRows(1); 251 | 252 | table.addCell("1.0"); 253 | table.addCell("1.1"); 254 | table.addCell("1.2"); 255 | table.addCell("2.1"); 256 | table.addCell("2.2"); 257 | table.addCell("2.3"); 258 | 259 | subCatPart.add(table); 260 | 261 | } 262 | 263 | private static void createList(Section subCatPart) { 264 | List list = new List(true, false, 10); 265 | list.add(new ListItem("First point")); 266 | list.add(new ListItem("Second point")); 267 | list.add(new ListItem("Third point")); 268 | subCatPart.add(list); 269 | } 270 | 271 | private static void addEmptyLine(Paragraph paragraph, int number) { 272 | for (int i = 0; i < number; i++) { 273 | paragraph.add(new Paragraph(" ")); 274 | } 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /app/src/main/java/casariego/jorge/createpdf/Pdf2Activity.java: -------------------------------------------------------------------------------- 1 | package casariego.jorge.createpdf; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.content.pm.PackageManager; 6 | import android.os.Bundle; 7 | import android.os.Environment; 8 | import android.support.v4.app.ActivityCompat; 9 | import android.support.v4.content.ContextCompat; 10 | import android.support.v7.app.AppCompatActivity; 11 | 12 | import com.itextpdf.text.Document; 13 | import com.itextpdf.text.DocumentException; 14 | import com.itextpdf.text.Element; 15 | import com.itextpdf.text.Paragraph; 16 | import com.itextpdf.text.pdf.PdfWriter; 17 | 18 | import java.io.FileNotFoundException; 19 | import java.io.FileOutputStream; 20 | 21 | public class Pdf2Activity extends AppCompatActivity { 22 | 23 | // Storage Permissions 24 | private static final int REQUEST_EXTERNAL_STORAGE = 1; 25 | 26 | private static String[] PERMISSIONS_STORAGE = { 27 | Manifest.permission.READ_EXTERNAL_STORAGE, 28 | Manifest.permission.WRITE_EXTERNAL_STORAGE 29 | }; 30 | 31 | 32 | @Override 33 | protected void onCreate(Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | setContentView(R.layout.activity_pdf2); 36 | 37 | verifyStoragePermissions(this); 38 | } 39 | 40 | /** 41 | * Checks if the app has permission to write to device storage 42 | * 43 | * If the app does not has permission then the user will be prompted to grant permissions 44 | * 45 | * @param activity 46 | */ 47 | public static void verifyStoragePermissions(Activity activity) { 48 | // Check if we have write permission 49 | if (ContextCompat.checkSelfPermission(activity, 50 | Manifest.permission.WRITE_EXTERNAL_STORAGE) 51 | != PackageManager.PERMISSION_GRANTED) { 52 | 53 | // Should we show an explanation? 54 | if (ActivityCompat.shouldShowRequestPermissionRationale(activity, 55 | Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 56 | 57 | // Show an expanation to the user *asynchronously* -- don't block 58 | // this thread waiting for the user's response! After the user 59 | // sees the explanation, try again to request the permission. 60 | 61 | } else { 62 | // No explanation needed, we can request the permission. 63 | ActivityCompat.requestPermissions(activity, 64 | PERMISSIONS_STORAGE, 65 | REQUEST_EXTERNAL_STORAGE); 66 | 67 | } 68 | 69 | 70 | } else { 71 | createPDF(); 72 | } 73 | } 74 | 75 | 76 | public static void createPDF(){ 77 | //create document object 78 | Document document=new Document(); 79 | 80 | //output file path 81 | String outpath= Environment.getExternalStorageDirectory()+"/PDF2.pdf"; 82 | 83 | try { 84 | PdfWriter.getInstance(document, new FileOutputStream(outpath)); 85 | document.open(); 86 | // Left 87 | Paragraph paragraph = new Paragraph("This is right aligned text"); 88 | paragraph.setAlignment(Element.ALIGN_RIGHT); 89 | document.add(paragraph); 90 | // Centered 91 | paragraph = new Paragraph("This is centered text"); 92 | paragraph.setAlignment(Element.ALIGN_CENTER); 93 | document.add(paragraph); 94 | // Left 95 | paragraph = new Paragraph("This is left aligned text"); 96 | paragraph.setAlignment(Element.ALIGN_LEFT); 97 | document.add(paragraph); 98 | // Left with indentation 99 | paragraph = new Paragraph("This is left aligned text with indentation"); 100 | paragraph.setAlignment(Element.ALIGN_LEFT); 101 | paragraph.setIndentationLeft(50); 102 | document.add(paragraph); 103 | 104 | document.close(); 105 | 106 | } catch (FileNotFoundException e) { 107 | // TODO Auto-generated catch block 108 | e.printStackTrace(); 109 | } catch (DocumentException e) { 110 | // TODO Auto-generated catch block 111 | e.printStackTrace(); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 13 | 14 |