Hi, We have been using iText to generate PDF reports. We have a 1 page PDF template(eg:Employee profile) which is populated at run time to generate reports. We use this template and generate a PDF report which will have multiple copies of this template(Profile report of multiple employees). PDF template is section 508 compliant. Tags, Reading order is set.
Approach 1: Please see the code below. We can generate reports perfectly fine but the report looses all it's accessibility tags. APPROACH 2: Please see the code below. Report keeps the accessibility tags but report has only 1 page i.e. Profile page of 1st record. While debugging, I see that it is filling the fields on AcroForm but somehow report does not contain those pages. Can you help us figure out what we are doing wrong ? Below is the code that we used: /################## APPROACH 1 file starts ################### /******************* MultiPdfView.java******************* public class MultiPdfView extends PdfView { protected int doPdf(HttpServletRequest request, Object pdfList, PdfCopyFields writer) throws Exception { if (pdfList == null) { return 0; } List valueList = (List) pdfList; int pdfLength = 0; Object[] objList; Object pdfObj; for (Iterator it = valueList.iterator(); it.hasNext();) { objList = (Object[]) it.next(); for (int i = 0; i < objList.length; i++) { pdfObj = objList[i]; pdfLength += addPdfPage(request, pdfObj, writer, this .getPdfPages()[i], pdfLength); } } return pdfLength; } } *******************/ /******************PdfView ******************* public class PdfView extends AbstractView { private PdfPageGenerator[] pdfPages; private String fileName; private String commandName; protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { WebUtils.exposeRequestAttributes(request, model); Object pdfObj = model.get(this.commandName); ServletOutputStream out = response.getOutputStream(); out.flush(); PdfCopyFields writer = new PdfCopyFields(out); int pdfLength = doPdf(request, pdfObj, writer); // write content type and also length (determined via byte array) response.setContentType("application/pdf"); response.setContentLength(pdfLength); response.setHeader("Content-disposition", "filename=" + this.fileName); // flush byte array to servlet output stream writer.getWriter().flush(); writer.close(); } protected int addPdfPages(HttpServletRequest request, Object pdfObj, PdfCopyFields writer) throws Exception { int pdfLength = 0; for (int i = 0; i < pdfPages.length; i++) { pdfLength += addPdfPage(request, pdfObj, writer, pdfPages[i], pdfLength); } return pdfLength; } protected int addPdfPage(HttpServletRequest request, Object pdfObj, PdfCopyFields writer, PdfPageGenerator pdfPage, int fieldIndexer) throws Exception { int pdfLength; String field; ByteArrayOutputStream baos = pdfPage.getStream(request, pdfObj); pdfLength = baos.toByteArray().length; PdfReader reader = new PdfReader(baos.toByteArray()); // Rename the fields AcroFields af = reader.getAcroFields(); // HashMap fields = (HashMap) af.getFields().clone(); // Iterator iter = fields.keySet().iterator(); // logger.debug(pdfPage.getTemplateFileName()); // while (iter.hasNext()) { // field = (String) iter.next(); // logger.debug(field); // // // use <code>fieldIndexer</code> to ensure that all the fields have // // different names // // it is the caller's responcibility to pass in the indexer variable // // with the correct inital value // af.renameField(field, new StringBuffer(field).append('_').append( // ++fieldIndexer).toString()); // } HashMap<String,AcroFields.Item> fieldsOriginal = (HashMap<String,AcroFields.Item>)af.getFields(); HashMap<String,AcroFields.Item> fields = (HashMap<String,AcroFields.Item>) fieldsOriginal.clone(); Iterator iter = fields.keySet( ).iterator( ); logger.debug(pdfPage.getTemplateFileName()); while ( iter.hasNext( ) ) { field = ( String ) iter.next( ); logger.debug(field); // use <code>fieldIndexer</code> to ensure that all the fields have different names // it is the caller's responcibility to pass in the indexer variable with the correct inital value af.renameField( field, new StringBuffer( field ).append( '_' ).append(++fieldIndexer).toString( ) ); } writer.addDocument(reader); return pdfLength; } protected int doPdf(HttpServletRequest request, Object pdfObj, PdfCopyFields writer) throws Exception { return addPdfPages(request, pdfObj, writer); } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public PdfPageGenerator[] getPdfPages() { return pdfPages; } public void setPdfPages(PdfPageGenerator[] pdfPages) { this.pdfPages = pdfPages; } public void setPdfPage(PdfPageGenerator pdfPage) { setPdfPages(new PdfPageGenerator[] { pdfPage }); } public String getCommandName() { return commandName; } public void setCommandName(String commandName) { this.commandName = commandName; } } *******************/ /********************PdfPageGenerator**************** public abstract class PdfPageGenerator { protected final Log log = LogFactory.getLog(getClass()); private ApplicationContext applicationContext; private PdfReader pdfReaderTemplate; private String templateFileName; public ByteArrayOutputStream getStream(HttpServletRequest request, Object command) throws Exception { if(pdfReaderTemplate == null) { pdfReaderTemplate = new PdfReader(request.getSession().getServletContext().getRealPath(this.templateFileName)); } ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfReader reader = new PdfReader(pdfReaderTemplate); PdfStamper stamp = new PdfStamper(reader, baos); AcroFields form = stamp.getAcroFields(); fillFields(request, form, command); stamp.close(); return baos; } protected abstract void fillFields(HttpServletRequest request, AcroFields form, Object command) throws Exception; public void setApplicationContext(ApplicationContext context) { this.applicationContext = context; } public PdfReader getPdfReaderTemplate() { return pdfReaderTemplate; } public void setPdfReaderTemplate(PdfReader pdfReaderTemplate) { this.pdfReaderTemplate = pdfReaderTemplate; } public String getTemplateFileName() { return templateFileName; } public void setTemplateFileName(String templateFileName) { this.templateFileName = templateFileName; } } *********************/ ######################APPROACH 1 files end #####################/ /############APPROACH 2 starts######################## /*******************MultiPdfView ******************** public class MultiPdfView extends PdfView { protected int doPdf(HttpServletRequest request, Object pdfList, ServletOutputStream out) throws Exception { if(pdfList == null) { return 0; } List valueList = (List) pdfList; int pdfLength = 0; Object[] objList; Object pdfObj; for (Iterator it = valueList.iterator(); it.hasNext(); ) { objList = (Object[]) it.next(); for(int i=0; i<objList.length; i++) { pdfObj = objList[i]; pdfLength += addPdfPage(request, pdfObj, out, this.getPdfPages()[i], pdfLength); } } return pdfLength; } } /******************************* /**********************************PdfView public class PdfView extends AbstractView { private PdfPageGenerator[] pdfPages; private String fileName; private String commandName; protected void renderMergedOutputModel(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { ServletOutputStream out = response.getOutputStream(); out.flush(); WebUtils.exposeRequestAttributes(request, model); Object pdfObj = model.get(this.commandName); //PdfCopyFields writer = new PdfCopyFields(out); int pdfLength = doPdf(request, pdfObj, out); // write content type and also length (determined via byte array) response.setContentType("application/pdf"); response.setContentLength(pdfLength); response.setHeader("Content-disposition", "filename="+this.fileName); // flush byte array to servlet output stream //writer.getWriter().flush(); //writer.close(); out.flush(); out.close(); } protected int addPdfPages(HttpServletRequest request, Object pdfObj, ServletOutputStream out) throws Exception { int pdfLength = 0; for (int i=0; i<pdfPages.length; i++) { pdfLength += addPdfPage(request, pdfObj, out, pdfPages[i], pdfLength); } return pdfLength; } protected int addPdfPage(HttpServletRequest request, Object pdfObj, ServletOutputStream out, PdfPageGenerator pdfPage, int fieldIndexer) throws Exception { int pdfLength; String field; ByteArrayOutputStream baos = pdfPage.getStream(request, pdfObj); pdfLength = baos.toByteArray().length; PdfReader reader = new PdfReader(baos.toByteArray()); // Rename the fields AcroFields af = reader.getAcroFields( ); //HashMap fields = ( HashMap ) af.getFields( ).clone( ); HashMap<String,AcroFields.Item> fieldsOriginal = (HashMap<String,AcroFields.Item>)af.getFields(); HashMap<String,AcroFields.Item> fields = (HashMap<String,AcroFields.Item>) fieldsOriginal.clone(); Iterator iter = fields.keySet( ).iterator( ); logger.debug(pdfPage.getTemplateFileName()); while ( iter.hasNext( ) ) { field = ( String ) iter.next( ); logger.debug(field); // use <code>fieldIndexer</code> to ensure that all the fields have different names // it is the caller's responcibility to pass in the indexer variable with the correct inital value af.renameField( field, new StringBuffer( field ).append( '_' ).append(++fieldIndexer).toString( ) ); } PdfStamper stamp = new PdfStamper(reader, out); stamp.close(); out.flush(); //writer.addDocument(reader); return pdfLength; } protected int doPdf(HttpServletRequest request, Object pdfObj, ServletOutputStream out) throws Exception { return addPdfPages(request, pdfObj, out); } public String getFileName() { return fileName; } public void setFileName(String fileName) { this.fileName = fileName; } public PdfPageGenerator[] getPdfPages() { return pdfPages; } public void setPdfPages(PdfPageGenerator[] pdfPages) { this.pdfPages = pdfPages; } public void setPdfPage(PdfPageGenerator pdfPage) { setPdfPages(new PdfPageGenerator[] {pdfPage}); } public String getCommandName() { return commandName; } public void setCommandName(String commandName) { this.commandName = commandName; } } ***********************************/ PdfPageGenerator.java is same as the first approach Thanks, abhi -- View this message in context: http://itext-general.2136553.n4.nabble.com/Success-with-Accessibility-Tags-but-prints-first-page-only-tp4657910.html Sent from the iText - General mailing list archive at Nabble.com. ------------------------------------------------------------------------------ Own the Future-Intel® Level Up Game Demo Contest 2013 Rise to greatness in Intel's independent game demo contest. Compete for recognition, cash, and the chance to get your game on Steam. $5K grand prize plus 10 genre and skill prizes. Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d _______________________________________________ iText-questions mailing list iText-questions@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/itext-questions iText(R) is a registered trademark of 1T3XT BVBA. Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/ Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php