本文介绍如何在C#中使用ItextSharp生成带echarts图表的pdf
一.生成一个简单的pdf
后台代码
publicActionResultGetPdf() { MemoryStream ms =newMemoryStream(); Document document =newDocument(); PdfWriter.GetInstance(document, ms); document.Open(); document.Add(newParagraph("Yes Master!")); document.Close(); returnFile(ms.ToArray(),"application/pdf","ceshi.pdf"); }
二.使pdf支持中文
后台代码
public ActionResult GetPdf() { it.Font font = new it.Font(BaseFont.CreateFont("C:\Windows\Fonts\simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 10); MemoryStream ms = new MemoryStream(); it.Document document = new it.Document(); PdfWriter.GetInstance(document, ms); document.Open(); document.Add(new it.Paragraph("Yes Master!")); document.Add(new it.Paragraph("其疾如风,其徐如林,侵掠如火,不动如山,难知如阴,动如雷震", font)); document.Close(); return File(ms.ToArray(), "application/pdf", "ceshi.pdf"); }
其他的文章中说需要引入两个另外的dll文件
这里面所写的再加入这两句话
BaseFont.AddToResourceSearch("iTextAsian.dll"); BaseFont.AddToResourceSearch("iTextAsianCmaps.dll");
测试了一下,5.5.5中并不需要再引入,也不需要加入这两句话(加了也没有用,因为会提示你没有AddToResourceSearch这个方法。。。。)
三.在pdf中加入图片
因为给我的需求是要求我将前台的echarts生成的图片在pdf中展示出来,于是可以将这个问题分成几个小问题来做
1.使用echarts生成图片并将其返回给后台
通过google,发现了如下资料:
http://www.oschina.net/question/586955_152417
但是是使用的java,而且其中有一些地方也没有写的很明白。
我这里使用的是C#
前台代码:
1 <!DOCTYPE html> 2 3 <html> 4 <head> 5 <meta name="viewport" content="width=device-width" /> 6 <title>ImagePdf</title> 7 <script src="http://cdn.bootcss.com/jquery/1.11.2/jquery.js"></script> 8 </head> 9 <body> 10 <div> 11 <button id="btnSearch" tabindex="999999" class="slbutton" style="border-style: none;"> 12 导出</button> 13 <div id="main" style="height: 400px"></div><input id="maininput" type="hidden"/> 14 <iframe id="exportContainer" style="display: none;"></iframe> 15 <script src="http://echarts.baidu.com/build/dist/echarts.js"></script> 16 <script type="text/javascript"> 17 $(function () { 18 $("#btnSearch").bind("click", function () { 19 ExportPDF(); 20 }); 21 }); 22 // 路径配置 23 require.config({ 24 paths: { 25 echarts: 'http://echarts.baidu.com/build/dist' 26 } 27 }); 28 29 // 使用 30 require( 31 [ 32 'echarts', 33 'echarts/chart/bar' // 使用柱状图就加载bar模块,按需加载 34 ], 35 function (ec) { 36 // 基于准备好的dom,初始化echarts图表 37 var myChart = ec.init(document.getElementById('main')); 38 39 var option = { 40 animation :false, 41 tooltip: { 42 show: true 43 }, 44 legend: { 45 data: ['销量'] 46 }, 47 xAxis: [ 48 { 49 type: 'category', 50 data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"] 51 } 52 ], 53 yAxis: [ 54 { 55 type: 'value' 56 } 57 ], 58 series: [ 59 { 60 "name": "销量", 61 "type": "bar", 62 "data": [5, 20, 40, 10, 10, 20] 63 } 64 ] 65 }; 66 67 // 为echarts对象加载数据 68 myChart.setOption(option); 69 $("#maininput").val(myChart.getDataURL('jpg')); 70 } 71 ); 72 function ExportPDF() { 73 74 var imgurl = $("#maininput").val(); 75 $.ajax({ 76 async: true, 77 type: "POST", 78 url: "/PdfDemo/SendImagePdfUrl", 79 cache: false, 80 timeout: 60 * 60 * 1000, 81 dataType: "json", 82 data: { 83 ImageUrl: imgurl 84 85 }, 86 success: function (result) { 87 if (result != null && result.message == "success") { 88 var src = "/PdfDemo/GetImagePdf?ID=" + result.filename; 89 $("#exportContainer").attr("src", src); 90 } 91 else { 92 if (result != null) { 93 alert(result.Message); 94 } 95 } 96 }, 97 beforeSend: function () { 98 $("#btnSearch").prop("disabled",true); 99 }, 100 complete: function () { 101 $("#btnSearch").prop("disabled", false); 102 } 103 }); 104 } 105 </script> 106 </div> 107 </body> 108 </html>
前台这里使用的echarts就不用介绍了吧,我将得到的base64的字符串保存到了页面的一个hidden里面(因为不知道如何在ExportPDF中调用echarts的函数得到这个字符串)。另外echarts还提供了getimage的方法,可以直接得到image图像,而这个getDataURL是在IE8下无法使用的(我用的是火狐)。另外这里有一点需要注意:那就是要将echarts的animation 设置为false,这样生成的图像才会有对应的柱形,否则只有坐标轴
2.将得到的base64字符串转化为Image
后台方法
SendImagePdfUrl控制器:
用来得到base64字符串并将其保存为jpg文件
public ActionResult SendImagePdfUrl(string ImageUrl) { JsonResult j = new JsonResult(); string fileName = System.Guid.NewGuid().ToString(); if (!string.IsNullOrEmpty(ImageUrl)) { Image pdfImage = base64ToPic(ImageUrl); pdfImage.Save(Server.MapPath("~") + "/pdfimage/" + fileName + "1.jpg"); var data = new { message = "success", filename = fileName }; j.Data = data;//返回单个对象; } else { var data = new { message = "未提供Url" }; j.Data = data;//返回单个对象; } return j; }
base64ToPic方法:
/// <summary> /// //对字节数组字符串进行Base64解码并生成图片 /// </summary> /// <param name="ImageUrl"></param> /// <returns></returns> public Image base64ToPic(string ImageUrl) { if (ImageUrl == null) //图像数据为空 { return null; } try { //将一开始的data:png等信息去掉,只剩base64字符串 String[] url = ImageUrl.Split(','); String u = url[1]; //Base64解码 byte[] imageBytes = Convert.FromBase64String(u); Image image; //生成图片 using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length)) { // Convert byte[] to Image ms.Write(imageBytes, 0, imageBytes.Length); image = Image.FromStream(ms, true); } return image; } catch (Exception e) { return null; } }
在后台将收到的请求对应的图片放入pdf并输出
public ActionResult GetImagePdf(string ID) { it.Font font = new it.Font(BaseFont.CreateFont("C:\Windows\Fonts\simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED), 10); MemoryStream ms = new MemoryStream(); it.Document document = new it.Document(); PdfWriter.GetInstance(document, ms); document.Open(); document.Add(new it.Paragraph("Yes Master!")); document.Add(new it.Paragraph("其疾如风,其徐如林,侵掠如火,不动如山,难知如阴,动如雷震", font)); List<string> imageStringList = GetImageString(ID, 1); foreach (var item in imageStringList) { try { //如果传过来的是Base64 //it.Image image = it.Image.GetInstance(base64ToPic(item), System.Drawing.Imaging.ImageFormat.Jpeg); //如果传过来的是地址 it.Image image = it.Image.GetInstance(Server.MapPath("~") + "/pdfimage/" + item + ".jpg"); image.Alignment = it.Image.ALIGN_LEFT; image.ScalePercent(30); document.Add(image); } catch (Exception e) { document.Add(new it.Paragraph("图片" + item + "不存在")); } } document.Close(); document.Dispose(); return File(ms.ToArray(), "application/pdf", "ceshi.pdf"); }
其他用到的方法:
/// <summary> /// 得到这一系列Image的Url /// </summary> /// <param name="ID">相同部分</param> /// <param name="count">共有几张</param> /// <returns></returns> public List<string> GetImageString(string ID, int count) { List<string> ImageStringList = new List<string>(); for (int i = 0; i < count; i++) { ImageStringList.Add(ID + count.ToString()); } return ImageStringList; }
至此,结束。
欢迎拍砖。