java+spring +mybatis+dojo项目中需要实现 将web 显示的table 数据和dojo chart 数据导入到pdf 文件,并支持pdf 下载 .
经过各种research,终于实现了,分享之.
1. 如何写table 数据到pdf:
用itext 插件(从http://sourceforge.net/projects/itext/files/ 下载itextpdf-XX.jar包)
2. 如何写chart 到pdf:
1) 转换dojo chart 为svg 文件,以便传递到server 端
2) svg 文件里面的数据可能不符合pdf 导入,需要替换
3) 传递到server 端,这一步,(由于下载文件必须用window.location 或是用window.open() , 而这是get 方式,参数上不能传递大量的数据,) ,用post 提交大参数数据传递到server ,server 端再将svg 内容put 到session ,用的时候再get from session
3. 如何下载pdf:
struts.xml 中要配置,action 用stream ,jsp 中用window.location
代码大致如下:
Struts.xml file
<package name="export" extends="json"> <action name="exportPDF" class="xx.action.ExportPDFAction"> <result name="success" type="stream"> <param name="contentType">application/pdf; charset=gb2312</param> <param name="inputName">pdfStream</param> <param name="contentDisposition">attachment;filename="${documentNames}"</param> <param name="bufferSize">4096</param> </result> </action> </package>
server side - Action file
package xx.action; import com.itextpdf.text.*; import com.itextpdf.text.pdf.*; import org.apache.batik.transcoder.TranscoderInput; import org.apache.batik.transcoder.print.PrintTranscoder; … @ParentPackage("export") ... public class ExportPDFAction extends ActionSupport { private InputStream pdfStream; private String documentNames; … public String saveSVGToSession(){ ActionContext context = ActionContext.getContext(); Map<String, Object> session = context.getSession(); session.put("actionSVG",actionSVG); return SUCCESS; } public String exportPDF() { DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); Date currentDate = new Date(); String pdfName=format.format(currentDate); documentNames="Metrics-"+pdfName+".pdf"; Document document = new Document(); try { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); PdfWriter writer=PdfWriter.getInstance(document, buffer); document.open(); Paragraph p=new Paragraph("(Data Range: "+startDate+" to "+endDate+")"); p.setAlignment(2); //align right document.add(p); document.add(new Paragraph("Metrics:")); PdfPTable table = new PdfPTable(2); table.setWidths(new int[]{ 2, 2 }); table.setWidthPercentage(100); PdfPCell cell; // row 1, cell 1 cell = new PdfPCell(new Phrase("Failure Count")); cell.setBackgroundColor(BaseColor.CYAN); cell.setVerticalAlignment(Element.ALIGN_CENTER); table.addCell(cell); // row 1, cell 2 cell = new PdfPCell(new Phrase("Data Count")); cell.setBackgroundColor(BaseColor.CYAN); cell.setVerticalAlignment(Element.ALIGN_CENTER); table.addCell(cell); // row 2 cell = new PdfPCell(new Phrase(Long.toString(failureCount))); cell.setVerticalAlignment(Element.ALIGN_CENTER); table.addCell(cell); ... document.add(table); document.add(new Paragraph("Chart: ")); Map session = ActionContext.getContext().getSession(); String content1=session.get("actionSVG").toString(); InputStream inputStream = new ByteArrayInputStream(content1.getBytes()); int width = 800; int height = 250; PdfContentByte cb = writer.getDirectContent(); PdfTemplate template = cb.createTemplate(width, height); Graphics2D g2 = template.createGraphics(width,height); PrintTranscoder prm = new PrintTranscoder(); TranscoderInput ti = new TranscoderInput(inputStream); prm.transcode(ti, null); PageFormat pg = new PageFormat(); Paper pp= new Paper(); pp.setSize(width, height); pp.setImageableArea(0, 0, width, height); pg.setPaper(pp); prm.print(g2, pg, 0); g2.dispose(); ImgTemplate img = new ImgTemplate(template); document.add(img); document.close(); this.pdfStream = new ByteArrayInputStream(buffer.toByteArray()); buffer.close(); return SUCCESS; } catch (DocumentException de) { System.err.println(de.getMessage()); return ERROR; } catch (IOException ioe) { System.err.println(ioe.getMessage()); return ERROR; } } public InputStream getPdfStream() { return pdfStream; } public void setPdfStream(InputStream pdfStream) { this.pdfStream = pdfStream; } … }
page side - js
function ExportToPDF() { var urlpath = "exportPDF!exportPDF?" + "&failureCount=" + dojo.byId("failureCount").value + "&dataCount=" + dojo.byId("dataCount").value + "&startDate=" + dojo.byId("startDate").value + "&endDate=" + dojo.byId("endDate").value; var drawing = dijit.byId("FailStat")._chart.chartObj.surface; var svg1 = dojox.gfx.utils.toSvg(drawing); var SVGContent = svg1.results[0]; SVGContent = SVGContent.replace(/text-anchor="left"/g, " "); dojo.xhrPost({ url:"exportPDF!saveSVGToSession", content:{"actionSVG": SVGContent }, load:function (data, ioargs) { window.location = encodeURI(urlpath); } }); }