I am using itext-5.3.4.jar and xmlworker-1.2.1.jar library for generate pdf from html string , html contains image logo and inline css.
My html file and image is in Asset folder , using this library my pdf generating successfully but there is no image display and no css style randering. anyone has a suggestion what should i do to fix this issue, if any other library or any other option for generate pdf from html will be helpful.
I am using these function for generate pdf:
public static void generatePdfFromHtlm(String fileName, String htmlString){
try {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory(), AppConfig.getContext().getPackageName() + "/" + "Pdf");
if (!mediaStorageDir.exists()) {
mediaStorageDir.mkdirs();
}
File fileWithinMyDir = new File(mediaStorageDir, fileName);
FontFactory.registerDirectories();
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream(fileWithinMyDir));
document.open();
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.setImageProvider(new AbstractImageProvider() {
public String getImageRootPath() {
Uri uri = Uri.parse("file:///android_asset/");
String newPath = uri.toString();
return newPath;
}
});
CSSResolver cssResolver =
XMLWorkerHelper.getInstance().getDefaultCssResolver(false);
/*Pipeline<?> pipeline =
new CssResolverPipeline(cssResolver,
new HtmlPipeline(htmlContext,
new PdfWriterPipeline(document, writer)));*/
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
InputStream is = new ByteArrayInputStream(htmlString.getBytes());
p.parse(is);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
my html file is
<!DOCTYPE html>
<!--[if IE 8]> <html lang="en" class="ie8"> <![endif]-->
<!--[if IE 9]> <html lang="en" class="ie9"> <![endif]-->
<!--[if !IE]><!-->
<html lang="en"> <!--<![endif]-->
<!-- BEGIN HEAD -->
<head>
<meta charset="utf-8" />
<title>WeighInsheet</title>
<style type="text/css">
body { font-family:Arial; }
.Wrapper { border:1px solid #cccccc; height:auto; margin:0px 65px;}
.header { height:105px; margin:5px; float:left;}
.logo { width:100px; height:100px; float:left; }
.heading { width:600px;}
h2{ margin:40px 0px 0px 0px;font-size: 22px; font-weight:bold;}
h3{ margin:0px; font-weight:normal;font-size: 16px;}
table { border-collapse: collapse; border-spacing: 0; width:100%; }
table td { font-family: arial; font-size: 14px; padding: 10px 5px; border: 1px solid #ddd; }
table th { background-color:#000000; color:#ffffff; font-family: arial; font-size: 16px; font-weight: bold;
border: 1px solid #ddd; }
</style>
</head>
<!-- END HEAD -->
<!-- BEGIN BODY -->
<body>
<div class="Wrapper">
<div class="header">
<div class="logo"><img src="logo.jpg" class="logo"/></div>
<div class="heading" align="center">
<h2>Description</h2>
<h3>Title Meta</h3>
</div>
</div>
<table>
<thead>
##CHANGEHEADER##
</thead>
<tbody>
##CHANGEBODY##
</tbody>
</table>
</div>
</body>
<!-- END BODY -->
</html>
My Image file "logo.jpg" is in asset folder .
I have Fixed Pdf Generate Issue With Xml Worker class.
For overcome CSS issues i have create external css file and apply it with the html.
For ex.
InputStream is = new ByteArrayInputStream(aHtmlString.getBytes());
InputStream css = new ByteArrayInputStream(cssString.getBytes());
XMLWorkerHelper.getInstance().parseXHtml(writer, document, is, css);
For Image Display issue copy your image From assets folder to phones internal folder.
Add give your img tag to that folder image path.
For ex.
<img src="/storage/emulated/0/MyApp/Images/my_logo.jpg"/>
Use This methods for copy files from asset to folder.
public static void listAssetFiles(String path,Context ctx,String folderPath) {
String [] list;
try {
list = ctx.getAssets().list(path);
if (list.length > 0) {
// This is a folder
for (String file : list) {
copyIntoFolder(file,ctx,path+"/",folderPath);
}
}
} catch (IOException e) {
}
}
public static void copyIntoFolder(String fileName, Context ctx, String filePath, String folderPath){
AssetManager assetManager = ctx.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filePath+fileName);
File outFile = new File(folderPath , fileName);
out = new FileOutputStream(outFile);
Utility.copyFile(in, out);
in.close();
// in = null;
out.flush();
out.close();
//out = null;
} catch(IOException e) {
Log.e("IOException", "copyIntoFolder: ",e );
}
}
Itext doesnt support all css properties below is a list of suported css properties, create your html according this supported css properties.
Css Support
iText Sharp is not supported all css property.You can load html in webview and generate pdf using this code.
private void createWebPrintJob(WebView webView) {
try {
PrintDocumentAdapter printAdapter;
String jobName = getString(R.string.app_name) + " Document";
PrintAttributes attributes = new PrintAttributes.Builder()
.setMediaSize(PrintAttributes.MediaSize.ISO_A4)
.setResolution(new PrintAttributes.Resolution("pdf", "pdf", 600, 600))
.setMinMargins(PrintAttributes.Margins.NO_MARGINS).build();
File path = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/AamirPDF/");
path.mkdirs();
PdfPrint pdfPrint = new PdfPrint(attributes);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
printAdapter = webView.createPrintDocumentAdapter(jobName);
} else {
printAdapter = webView.createPrintDocumentAdapter();
}
pdfPrint.printNew(printAdapter, path, "output_" + System.currentTimeMillis() + ".pdf", getActivity().getCacheDir().getPath());
} catch (Exception e) {
e.printStackTrace();
}
}
PdfPrint class for generate PDF.
package com.example.nisarg.invoice;
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.util.Log;
import com.example.nisarg.invoice.android.print.ProxyBuilder;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import static com.example.nisarg.invoice.Database.appglobal.context;
public class PdfPrint {
public static final String TAG = PdfPrint.class.getSimpleName();
public static PrintAttributes printAttributes;
File cacheFolder;
public PdfPrint(PrintAttributes printAttributes) {
this.printAttributes = printAttributes;
cacheFolder = new File(context.getFilesDir() + "/etemp/");
}
public static PrintDocumentAdapter.WriteResultCallback getWriteResultCallback(InvocationHandler invocationHandler,
File dexCacheDir) throws IOException {
return ProxyBuilder.forClass(PrintDocumentAdapter.WriteResultCallback.class)
.dexCache(dexCacheDir)
.handler(invocationHandler)
.build();
}
public static PrintDocumentAdapter.LayoutResultCallback getLayoutResultCallback(InvocationHandler invocationHandler,
File dexCacheDir) throws IOException {
return ProxyBuilder.forClass(PrintDocumentAdapter.LayoutResultCallback.class)
.dexCache(dexCacheDir)
.handler(invocationHandler)
.build();
}
/* public void print(final PrintDocumentAdapter printAdapter, final File path, final String fileName) {
printAdapter.onLayout(null, printAttributes, null, new PrintDocumentAdapter.LayoutResultCallback() {
@Override
public void onLayoutFinished(PrintDocumentInfo info, boolean changed) {
try {
PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if (method.getName().equals("onWriteFinished")) {
// pdfCallback.onPdfCreated();
} else {
Log.e(TAG, "Layout failed");
// pdfCallback.onPdfFailed();
}
return null;
}
}, null);
printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback);
} catch (IOException e) {
e.printStackTrace();
}
}
}, null);
}*/
public void printNew(final PrintDocumentAdapter printAdapter, final File path, final String fileName, final String fileNamenew) {
try {
printAdapter.onStart();
printAdapter.onLayout(null, printAttributes, new CancellationSignal(), getLayoutResultCallback(new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if (method.getName().equals("onLayoutFinished")) {
onLayoutSuccess(printAdapter, path, fileName, fileNamenew);
} else {
Log.e(TAG, "Layout failed");
}
return null;
}
}, new File(fileNamenew)), new Bundle());
} catch (Exception e) {
e.printStackTrace();
}
}
private void onLayoutSuccess(PrintDocumentAdapter printAdapter, File path, String fileName, String filenamenew) throws IOException {
PrintDocumentAdapter.WriteResultCallback callback = getWriteResultCallback(new InvocationHandler() {
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
if (method.getName().equals("onWriteFinished")) {
System.out.print("hello");
} else {
Log.e(TAG, "Layout failed");
}
return null;
}
}, new File(filenamenew));
printAdapter.onWrite(new PageRange[]{PageRange.ALL_PAGES}, getOutputFile(path, fileName), new CancellationSignal(), callback);
}
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;
}
}
Generate Proxy of class.[https://gist.github.com/brettwold/838c092329c486b6112c8ebe94c8007e ]
For dependence which is used in proxy builder class add this line in gradle.
compile 'com.linkedin.dexmaker:dexmaker-mockito:2.2.0'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With