最近客户提出一个需求,就是把页面上的图表导出为pdf文件。
找了很多资料。终于有了点头绪。最主要是参考了HighCharts的做法。http://www.hcharts.cn/
实现原理:把页面图表的svg内容发送到后台,后台生成pdf图片文件流,返回。
但是遇到问题,用jquery的post请求,不能下载文件;用get请求方式,svg数据可能很多,传不过来;最后用了如下方法,创建一个隐藏的form来sumbit.
前台代码片段:
$("#btn").click(function () {
var f = document.createElement("form");
document.body.appendChild(f);
var i = document.createElement("input");
i.type = "hidden";
f.appendChild(i);
i.value = $("#r").html();
i.name = "svg";
var j = document.createElement("input");
j.type = "hidden";
f.appendChild(j);
j.value = "pdf";
j.name = "tpye";
f.method = "post";
f.enctype="multipart/form-data"
f.action = "/Chart/Export";
f.submit();
});
后台代码片段:后台会用到两个第三方的dll(itextsharp.dll和Svg.dll)
//HighCharts 导出图片 svg
//filename type width scale svg
[HttpPost]
[ValidateInput(false)]
public ActionResult Export(FormCollection fc)
{
try
{
string tType = fc["type"];
tType = "application/pdf";
string tSvg = fc["svg"];
string tFileName = fc["filename"];
if (string.IsNullOrEmpty(tFileName))
tFileName = "chart";
MemoryStream tData = new MemoryStream(Encoding.UTF8.GetBytes(tSvg));
MemoryStream tStream = new MemoryStream();
string tTmp = new Random().Next().ToString();
string tExt = "";
string tTypeString = "";
switch (tType)
{
case "image/png":
tTypeString = "-m image/png";
tExt = "png";
break;
case "image/jpeg":
tTypeString = "-m image/jpeg";
tExt = "jpg";
break;
case "application/pdf":
tTypeString = "-m application/pdf";
tExt = "pdf";
break;
case "image/svg+xml":
tTypeString = "-m image/svg+xml";
tExt = "svg";
break;
}
if (tTypeString != "")
{
string tWidth = fc["width"];
Svg.SvgDocument tSvgObj = SvgDocument.Open(tData);
switch (tExt)
{
case "jpg":
tSvgObj.Draw().Save(tStream, ImageFormat.Jpeg);
break;
case "png":
tSvgObj.Draw().Save(tStream, ImageFormat.Png);
break;
case "pdf":
PdfWriter tWriter = null;
Document tDocumentPdf = null;
try
{
//tSvgObj.Draw().Save(tStream, ImageFormat.Png);
tDocumentPdf = new Document(new iTextSharp.text.Rectangle((float)tSvgObj.Width, (float)tSvgObj.Height));
tDocumentPdf.SetMargins(0.0f, 0.0f, 0.0f, 0.0f);
iTextSharp.text.Image tGraph = iTextSharp.text.Image.GetInstance(tStream.ToArray());
tGraph.ScaleToFit((float)tSvgObj.Width, (float)tSvgObj.Height);
tStream = new MemoryStream();
tWriter = PdfWriter.GetInstance(tDocumentPdf, tStream);
tDocumentPdf.Open();
tDocumentPdf.NewPage();
tDocumentPdf.Add(tGraph);
tDocumentPdf.Close();
}
catch (Exception ex)
{
throw ex;
}
finally
{
tDocumentPdf.Close();
tWriter.Close();
tData.Dispose();
tData.Close();
}
break;
case "svg":
tStream = tData;
break;
}
}
return File(tStream.ToArray(), tType, tFileName);
}
catch (Exception ex)
{
return Content(ex.Message);
}
}