Hello list,
i am using itext to combine several pdfs to one result pdf. The pdf generation
is done by a service that
returns a byte stream back to the browser that requested the pdf. From here the
user can decide to save
the pdf or to open it right away.
The service looks like:
ByteArrayOutputStream generatePDF(params)
My problem is that the resulting pdf is corrupt. Some acrobat readers cannot
open the file, on my
mac i can open the file with acrobat8 that flashes a pop up for a very short
period saying "repairing.." or
something, with the preview mac-application opening the pdf is not possible.
The pdf is composed of 5 separate pdfs. One is "dynamic" as it fields are
filled with values programatically,
the other parts are static as they exist already and are simply "pasted" after
the first dynamic one.
This is how the static pdfs are attached to the result pdf (outStream):
void combinePDFs(OutputStream outStream, InputStream ... pdfStreams) throws
IOException, DocumentException
{
PdfCopyFields copy = new PdfCopyFields(outStream);
for(InputStream in : pdfStreams)
{
if(in == null)
continue;
PdfReader r = new PdfReader(in);
copy.addDocument(r);
}
copy.close();
}
I am using itext2.0.5 and jdk1.5. The static source pdfs already exist,
generated by any kind of software in any version,
the only thing I know is they are pdfs and can be opened by acrobat reader.
I attached the whole class that handles the pdf generation, maybe someone can
see a mistake in using the itext api.
Thanks,
Chris
______________________________________________________________________________
Jetzt neu! Im riesigen WEB.DE Club SmartDrive Dateien freigeben und mit
Freunden teilen! http://www.freemail.web.de/club/smartdrive_ttc.htm/?mc=021134
package de.toptarif.category.electricity.impl.pdf;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfCopyFields;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import de.toptarif.category.electricity.ElectricityDocumentException;
import de.toptarif.category.electricity.IDocumentContainer;
import de.toptarif.category.electricity.IElectricityProductDocumentService;
public class ToptarifPDFgenerator implements IToptarifPDFgenerator
{
private static final Log log = LogFactory.getLog(ToptarifPDFgenerator.class);
private IElectricityProductDocumentService productDocumentService;
private IPaymentTextBuilder paymentTextBuilder;
public ToptarifPDFgenerator(IElectricityProductDocumentService
productDocumentService, IPaymentTextBuilder paymentTextBuilder)
{
super();
this.productDocumentService = productDocumentService;
this.paymentTextBuilder = paymentTextBuilder;
}
/**
* Generates the pdf consisting of 3 parts: Aplpication form, provider info
* and toptarif info
*
* @param toptarifCustomer
* the customer
* @param formpdf
* the pdf Stream for the application form
* @param providerpdf
* the pdf stream for the provider info
* @param toptarifpdf
* the pdf form for the toptarif info
* @param outStream
* the output stream that the generated pdf is written to
* @throws IOException
* @throws DocumentException
* @throws ElectricityDocumentException
*/
public ByteArrayOutputStream generatePDF(ITopTarifCustomer toptarifCustomer,
String tarrifProductId) throws IOException, DocumentException
{
return generatePDF(toptarifCustomer, tarrifProductId, false);
}
private InputStream loadResource(String resource)
{
return
Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
}
public ByteArrayOutputStream generatePDF(ITopTarifCustomer toptarifCustomer,
String tarrifProductId, boolean firstPageOnly) throws IOException
,DocumentException
{
InputStream topTarifMainPDF = loadResource("toptarif_3.pdf");
if(firstPageOnly)
{
IDocumentContainer productAgbAndLogo = null;
try
{
productAgbAndLogo =
productDocumentService.getAgbAndLogoForProduct(tarrifProductId);
}
catch (ElectricityDocumentException e)
{
// ignore missing terms/logo
}
ByteArrayOutputStream result = new ByteArrayOutputStream();
fillPDFForm(toptarifCustomer, topTarifMainPDF, productAgbAndLogo ==
null ? null : productAgbAndLogo.getLogo(), result, tarrifProductId, true);
return result;
}
InputStream topTarifBrochurePDF = loadResource("brochure.pdf");
InputStream topTarifReplySheetPDF = loadResource("antwortbogen.pdf");
IDocumentContainer productAgbAndLogo = null;
try
{
productAgbAndLogo =
productDocumentService.getAgbAndLogoForProduct(tarrifProductId);
} catch (ElectricityDocumentException e)
{
throw new DocumentException(e);
}
InputStream providerAgbPDF = productAgbAndLogo.getAgbDocument();
InputStream supplierLogo = productAgbAndLogo.getLogo();
// In-Memory temp stream for the form PDF ...
ByteArrayOutputStream result = new ByteArrayOutputStream();
// Fill in the form PDF ...
fillPDFForm(toptarifCustomer, topTarifMainPDF, supplierLogo, result,
tarrifProductId, false);
// Get the Form as In-Memory Inputstream ...
ByteArrayInputStream tempFormPdfInputStream = new
ByteArrayInputStream(result.toByteArray());
String evuId = productDocumentService.getEvuIdByProductId(tarrifProductId);
InputStream evuBrochure = null;
if(productDocumentService.isEvuBrochureAvailable(evuId))
evuBrochure = productDocumentService.getEvuBrochure(evuId);
if(evuBrochure == null)
log.warn("found no evu-brochure for evu_id '"+evuId+"'");
// Combines all PDF parts
combinePDFs(result, tempFormPdfInputStream, evuBrochure, providerAgbPDF,
topTarifBrochurePDF, topTarifReplySheetPDF);
return result;
}
public boolean sufficientInfoForPdf(String tarrifProductId)
{
try
{
productDocumentService.getAgbAndLogoForProduct(tarrifProductId);
} catch (ElectricityDocumentException e)
{
log.error("Not sufficient info for PDF creation, could not find agb
and/or logo. for product id " + tarrifProductId + ".", e);
return false;
}
return true;
}
/**
* combines all three pdfs (form, provider info, toptarif info)
*
* @param formpdf
* @param providerpdf
* @param toptarifpdf
* @param outStream
* @throws IOException
* @throws DocumentException
*/
private void combinePDFs(OutputStream outStream, InputStream ... pdfStreams)
throws IOException, DocumentException
{
PdfCopyFields copy = new PdfCopyFields(outStream);
for(InputStream in : pdfStreams)
{
// be fault tolerant
if(in == null)
continue;
PdfReader r = new PdfReader(in);
copy.addDocument(r);
}
copy.close();
}
/**
* Fills in the PDF application form
*
* @param energieUser
* the customer data
* @param formpdf
* the form inputstream
* @param outStream
* the outputstream
* @throws IOException
* @throws DocumentException
*/
private void fillPDFForm(ITopTarifCustomer energieUser, InputStream formpdf,
InputStream supplierLogo, OutputStream outStream, String tariffProductId,
boolean faultTolerant) throws IOException, DocumentException
{
// we create a reader for a certain document
PdfReader reader = new PdfReader(formpdf);
// filling in the form
PdfStamper stamp = new PdfStamper(reader, outStream);
try
{
AcroFields form = stamp.getAcroFields();
fillContract(form, energieUser);
fillPerson(form, "billing", energieUser.getBiller());
fillPerson(form, "customer", energieUser.getCustomer());
fillBank(form, energieUser.getBankAccount());
fillSupplier(form, energieUser.getSupplier(), tariffProductId);
try
{
setSupplierImage(stamp, form, energieUser.getSupplier(),
supplierLogo);
}
catch(Exception e)
{
if(!faultTolerant)
throw new RuntimeException("failure while setting supplier
logo", e);
}
if (energieUser.getMoveIn() == ITopTarifCustomer.MoveIn.YES)
{
// yes, this is true: set "0" for "true"
form.setField("move_in", "0");
form.setField("move_in_date", energieUser.getMoveInDate());
} else if (energieUser.getMoveIn() == ITopTarifCustomer.MoveIn.NO)
{
form.setField("move_in", "1");
}
stamp.setFormFlattening(false); // true = uneditable Fromular#
} finally
{
stamp.close();
reader.close();
}
}
/**
* Fill in the Form Contract infos
*
* @param form
* @param energieUser
* @throws IOException
* @throws DocumentException
*/
private void fillContract(AcroFields form, ITopTarifCustomer energieUser)
throws IOException, DocumentException
{
if (energieUser != null)
{
form.setField("agent_id", energieUser.getAgentNumber());
form.setField("contract_id", energieUser.getContractNumber());
form.setField("job_id", energieUser.getApplicationNumber());
}
}
/**
* Fill in the form Supplier Infos ...
*
* @param form
* @param supplier
* @throws IOException
* @throws DocumentException
*/
private void fillSupplier(AcroFields form, ISupplier supplier, String
tariffProductId) throws IOException, DocumentException
{
if (supplier != null)
{
form.setField("current_customer_id", supplier.getCurrentCustomerId());
form.setField("current_supplier", supplier.getCurrentSupplier());
form.setField("electric_meter_value", supplier.getElectricMeterValue());
form.setField("electric_meter_value_2",
supplier.getElectricMeterValue2());
form.setField("electric_meter_date", supplier.getElectricMeterDate());
form.setField("electric_meter_id", supplier.getElectricMeterId());
form.setField("yearly_usage", supplier.getYearlyUsage());
form.setField("supplier_tariff", supplier.getSupplierTarif());
try
{
form.setField("payment_info",
paymentTextBuilder.calculatePaymentText(tariffProductId,
Integer.parseInt(supplier.getYearlyUsage())));
} catch (ElectricityDocumentException e)
{
// TODO refactor this to throw e upper
log.error("Error setting payment text in PDF.", e);
}
}
}
/**
* Fill in the Form Bank infos
*
* @param form
* @param bank
* @throws IOException
* @throws DocumentException
*/
private void fillBank(AcroFields form, IBankAccount bank) throws IOException,
DocumentException
{
if (bank != null)
{
form.setField("account_number", "" + bank.getAccountNumber());
form.setField("account_holder", bank.getAccountHolder());
form.setField("bank_code", "" + bank.getBankCode());
form.setField("bank", bank.getBank());
}
}
/**
* Fill in the Form person infos
*
* @param form
* @param fild
* @param person
* @throws IOException
* @throws DocumentException
*/
private void fillPerson(AcroFields form, String fild, IPerson person) throws
IOException, DocumentException
{
if (person != null)
{
if (person.getSalutation() == IPerson.Salutation.MAN)
{
form.setField(fild + "_salutation", "1");
} else if (person.getSalutation() == IPerson.Salutation.WOMAN)
{
form.setField(fild + "_salutation", "2");
} else if (person.getSalutation() == IPerson.Salutation.FIRM)
{
form.setField(fild + "_salutation", "3");
} else
{
form.setField(fild + "_salutation", "0");
}
form.setField(fild + "_adress_suffix", person.getAdressSuffix());
form.setField(fild + "_date_of_birth", person.getDateOfBirth());
form.setField(fild + "_adress", person.getAdress());
form.setField(fild + "_name", person.getName());
form.setField(fild + "_email", person.getEMail());
form.setField(fild + "_phone_number", person.getTelefon());
form.setField(fild + "_zip_city", person.getZipCity());
// }
}
}
/**
* Set the Supplier Image in the Form ...
*
* @param stamp
* @param form
* @param supplier
* @throws MalformedURLException
* @throws IOException
* @throws DocumentException
*/
private void setSupplierImage(PdfStamper stamp, AcroFields form, ISupplier
supplier, InputStream supplierLogo) throws MalformedURLException, IOException,
DocumentException
{
// AcroFields form = stamp.getAcroFields();
float[] photograph = form.getFieldPositions("supplier_logo");
Rectangle rect = new Rectangle(photograph[1], photograph[2], photograph[3],
photograph[4]);
ByteArrayOutputStream out = new ByteArrayOutputStream();
int b;
while((b = supplierLogo.read()) > -1) {
out.write(b);
}
Image image = Image.getInstance(out.toByteArray());
// Image image = Image.getInstance(supplier.getSupplierLogo());
image.scaleToFit(rect.getWidth(), rect.getHeight() * 2);
image.setAbsolutePosition(photograph[1] + (rect.getWidth() -
image.getScaledWidth()) / 2, photograph[2] + (rect.getHeight() -
image.getScaledHeight()) - 2);
PdfContentByte cb = stamp.getOverContent((int) photograph[0]);
cb.addImage(image);
}
}-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems? Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://itext.ugent.be/itext-in-action/