Monday, December 28, 2009

/*
* AbstractPdfStamperView.java
* Created to make the process of merging field data on an AcroForm easy to do in Spring.
*
* @author K. Bryant Larsen
*/

package edu.utah.oit.osl.controller.web.view;

import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.view.AbstractView;

/**
* This abstract class is intended to be used for the merging of
* existing PDF forms with data and will write the PDF to the response.
* Similar to Springs AbstractPdfView except there is no document in this version.
* Created on March 26, 2008, 12:09 PM
* @author Bryant Larsen Media Solutions The University of Utah
*/
public abstract class AbstractPdfStamperView extends AbstractView {

private String url;
private static final int OUTPUT_BYTE_ARRAY_INITIAL_SIZE = 1024;

public AbstractPdfStamperView(){
super();
setContentType("application/pdf");
}

/**This is the method that will put all of the peices together and send the final output down to the response.
* @param model A Map that contains the model data for this instance
* @param request The request that will be handed to this view.
* @param response Contains the byte array outpu stream to output to the actuall browser.
*/
protected final void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception{
//Hold our output in a temporary output stream.
ByteArrayOutputStream tempOutputStream = new ByteArrayOutputStream(AbstractPdfStamperView.OUTPUT_BYTE_ARRAY_INITIAL_SIZE);
//Get the file from the filesystem.
PdfReader reader = new PdfReader(this.getServletContext().getResourceAsStream(this.getUrl()));
//Get a PdfStamper instance that will give us access to the AcroField
PdfStamper stamper = new PdfStamper(reader, tempOutputStream);
//Give the user the chance to merge the form fields.
mergePdfDocument(model, stamper, request, response);
//Set various settings on the stamper object.
//Example, stamper.setFormFlattening(true);
prepareStamper(stamper);
//Close the stamper
stamper.close();
// Write content type and also length(determined via byte array).
response.setContentType(getContentType());
response.setContentLength(tempOutputStream.size());

// Flush byte array to servlet output stream.
ServletOutputStream out = response.getOutputStream();
tempOutputStream.writeTo(out);
out.flush();
}

/**
* Abstract method that subclasses must implement.

* This is where you are able to set values on the AcroForm.

* An example of what can be done at this level is:


* //get the form from the document:

* AcroFields form = stamper.getAcroFields();

*

* //Set some values on the form.

* form.setField("field1", "Value1");

* form.setField("field2", "Value2");


* //Set the disposition and filename

* response.setHeader("Content-disposition", "attachment; FILENAME=someName.pdf" );
*@param model The model
*@param stamper The PdfStamper instance that will containt he AcroFields.
*@param request Provided in case you want to get parameters directly from the request
*@param response Provided for setting cookies or other things. Do not attempt to write the stamper to the outputstream. That is done in a different method.
*
*/
protected abstract void mergePdfDocument(Map model, com.lowagie.text.pdf.PdfStamper stamper, HttpServletRequest request, HttpServletResponse response) throws Exception ;

/** This method is run After the MergePdfDocument and Before the stamper is closed.

* This gives you an oportunity set your own settings on the stamper.
* This is where we suggest that you set things like setFormFlattening and many other interesting things.
* @param stamper. The stamper object that has already been merged.
*/
protected abstract void prepareStamper(PdfStamper stamper);


/** The url in this case is a string value that represents the existing PDF file that will be used to generate the stamper.
* You can use the view setup to specify the url. mergePdf.(class)=.PdfStamperClass mergePdf.url=/WEB-INF/views/resources/template.pdf
* will set the url as /WEB-INF/views/resources/template.pdf.
* @param url The file location to the PDF document.
*/
public void setUrl(String url) {
this.url = url;
}

/** JavaBean method to retreive the document url from the instance.
* @return url.
*/
public String getUrl() {
return this.url;
}






}

No comments: