本文介紹如何在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; }
至此,結束。
歡迎拍磚。