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);
}
});
}