一 前言
最近做了一個周報,從不同的數據表抓取數據,然后展示到前端頁面顯示。這個過程不難,讓我煩惱的是:要把周報的數據導出來,然后打印,打印也必須在一張紙上。想到這里,我整理了一下思緒,我要寫幾個存儲過程,存儲過程里有很多復雜的邏輯元素。要做個導出功能,還必須在一張A4紙上打印出來。納尼?必須在一張紙上打印!然后我翻閱了資料和問了度娘。html2canvas插件可以實現我的需求。一開始我是很高興的,因為能行。接下來我就發現了一些問題:
1.下載下來的js,運行直接報錯,Oh,天吶!
2.有些瀏覽器根本不支持a標簽下載圖片。
3.圖片沒有那么清晰,比較模糊。
4.下載到本地的圖片不完全,這個很致命。
兜兜轉轉,終於搞定了。記錄此刻!
二 准備
1 <script src="~/Scripts/jquery-1.8.2.js"></script> 2 <script src="~/Scripts/html2canvas.min.js"></script> 3 <script src="~/Scripts/bluebird.js"></script>
三 Demo/js
1 @using PlatForm.ERP.Models.Reports 2 @using PlatForm.ERP.Models.Daily 3 @model WeekReportSummaryAndPlanModel 4 @{ 5 var webSiteName = ViewBag.WebSiteName; 6 var weekName = ViewBag.WeekName; 7 var operateDayOrWeekReport = ViewBag.OperateDayOrWeekReport as OperateDayOrWeekReportModel; 8 var storeVisitorFlowRateDayOrWeekReports = ViewBag.StoreVisitorFlowRateDayOrWeekReports as IList<StoreVisitorFlowRateDayOrWeekReportModel>; 9 var singleProductDayOrWeekReports = ViewBag.SingleProductDayOrWeekReports as IList<SingleProductDayOrWeekReportModel>; 10 var weekReportSummaryAndPlan = ViewBag.WeekReportSummaryAndPlan as WeekReportSummaryAndPlanModel; 11 } 12 <style type="text/css"> 13 td { 14 border: 1px solid #ccc; 15 } 16 </style> 17 <div style="float:right;"><input type="button" id="btn" class="k-button" value="保存為圖片" /></div> 18 <div id="imgDiv" style="padding-top:30px;"> 19 <div> 20 <table class="zTable" cellpadding="0" cellspacing="0" style="width:80%;text-align:center;background-color:white;"> 21 <tr> 22 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">店鋪運營基礎數據</td> 23 </tr> 24 <tr> 25 <td style="font-weight:bolder;">日期</td> 26 <td style="font-weight:bolder;">成交金額</td> 27 <td style="font-weight:bolder;">訪客數</td> 28 <td style="font-weight:bolder;">去年訪客數</td> 29 <td style="font-weight:bolder;">訪客數同比</td> 30 <td style="font-weight:bolder;">瀏覽量</td> 31 <td style="font-weight:bolder;">去年瀏覽量</td> 32 <td style="font-weight:bolder;">瀏覽量同比</td> 33 </tr> 34 @if (operateDayOrWeekReport != null) 35 { 36 <tr> 37 <td style="font-weight:bolder;" rowspan="10">@operateDayOrWeekReport.WeekName</td> 38 <td>@operateDayOrWeekReport.DealAmount</td> 39 <td>@operateDayOrWeekReport.VisitorCount</td> 40 <td>@operateDayOrWeekReport.BeforeYearVisitorCount</td> 41 <td>@operateDayOrWeekReport.VisitorCountYearOnYear</td> 42 <td>@operateDayOrWeekReport.BrowseVolume</td> 43 <td>@operateDayOrWeekReport.BeforeYearBrowseVolume</td> 44 <td>@operateDayOrWeekReport.BrowseVolumeYearOnYear</td> 45 </tr> 46 } 47 <tr> 48 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">下單</td> 49 </tr> 50 <tr> 51 <td style="font-weight:bolder;">下單客戶數</td> 52 <td style="font-weight:bolder;">下單單量</td> 53 <td style="font-weight:bolder;">下單商品件數</td> 54 <td style="font-weight:bolder;">下單金額</td> 55 </tr> 56 @if (operateDayOrWeekReport != null) 57 { 58 <tr> 59 <td>@operateDayOrWeekReport.OrderCustomerCount</td> 60 <td>@operateDayOrWeekReport.OrderQuantity</td> 61 <td>@operateDayOrWeekReport.OrderProductCount</td> 62 <td>@operateDayOrWeekReport.OrderAmount</td> 63 </tr> 64 } 65 <tr> 66 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">成交</td> 67 </tr> 68 <tr> 69 <td style="font-weight:bolder;">成交客戶數</td> 70 <td style="font-weight:bolder;">成交單量</td> 71 <td style="font-weight:bolder;">成交商品件數</td> 72 <td style="font-weight:bolder;">客單價</td> 73 <td style="font-weight:bolder;">實際銷售件數</td> 74 <td style="font-weight:bolder;">實際銷售金額</td> 75 <td style="font-weight:bolder;">去年實際銷售</td> 76 <td style="font-weight:bolder;">退貨件數</td> 77 <td style="font-weight:bolder;">退貨金額</td> 78 <td style="font-weight:bolder;">去年退貨金額</td> 79 <td style="font-weight:bolder;">下單轉化率</td> 80 <td style="font-weight:bolder;">成交轉化率</td> 81 <td style="font-weight:bolder;">下單成交轉化率</td> 82 </tr> 83 @if (operateDayOrWeekReport != null) 84 { 85 <tr> 86 <td>@operateDayOrWeekReport.DealCustomerCount</td> 87 <td>@operateDayOrWeekReport.DealQuantity</td> 88 <td>@operateDayOrWeekReport.DealProductCount</td> 89 <td>@operateDayOrWeekReport.CustomerPrice</td> 90 <td>@operateDayOrWeekReport.RealSaleCount</td> 91 <td>@operateDayOrWeekReport.RealSaleAmount</td> 92 <td>@operateDayOrWeekReport.BeforeYearRealSale</td> 93 <td>@operateDayOrWeekReport.ReturnCount</td> 94 <td>@operateDayOrWeekReport.ReturnAmount</td> 95 <td>@operateDayOrWeekReport.BeforeYearReturn</td> 96 <td>@operateDayOrWeekReport.OrderConversionRate</td> 97 <td>@operateDayOrWeekReport.ConversionRate</td> 98 <td>@operateDayOrWeekReport.OrderDealConversionRate</td> 99 </tr> 100 } 101 <tr> 102 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">費用</td> 103 </tr> 104 <tr> 105 <td style="font-weight:bolder;">補單佣金</td> 106 <td style="font-weight:bolder;">活動</td> 107 <td style="font-weight:bolder;">快車</td> 108 <td style="font-weight:bolder;">其他</td> 109 </tr> 110 @if (operateDayOrWeekReport != null) 111 { 112 <tr> 113 <td>@operateDayOrWeekReport.SupplementOrderCommission</td> 114 <td>@operateDayOrWeekReport.Activitie</td> 115 <td>@operateDayOrWeekReport.KuaiChe</td> 116 <td>@operateDayOrWeekReport.OtherFee</td> 117 </tr> 118 } 119 </table> 120 </div> 121 <div style="padding-top:50px;"> 122 <table class="zTable" cellpadding="0" cellspacing="0" style="width:80%;text-align:center; background-color:white;"> 123 <tr> 124 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">店鋪流量</td> 125 </tr> 126 <tr> 127 <td style="font-weight:bolder;">日期</td> 128 <td style="font-weight:bolder;">來源</td> 129 <td style="font-weight:bolder;">訪客數</td> 130 <td style="font-weight:bolder;">訪客數占比</td> 131 <td style="font-weight:bolder;">上周訪客數</td> 132 <td style="font-weight:bolder;">上周訪客數占比</td> 133 <td style="font-weight:bolder;">去年同時期訪客數</td> 134 <td style="font-weight:bolder;">去年同時期訪客數占比</td> 135 <td style="font-weight:bolder;">環比(訪客數)</td> 136 <td style="font-weight:bolder;">同比(訪客數)</td> 137 </tr> 138 139 @if (storeVisitorFlowRateDayOrWeekReports != null) 140 { 141 foreach (var item in storeVisitorFlowRateDayOrWeekReports) 142 { 143 <tr> 144 <td style="font-weight:bolder;">@item.WeekName</td> 145 <td>@item.Source</td> 146 <td>@item.VisitorCount</td> 147 <td>@item.VisitorCountProportion</td> 148 <td>@item.BeforeDayOrWeekVisitorCount</td> 149 <td>@item.BeforeDayOrWeekVisitorCountProportion</td> 150 <td>@item.BeforeYearVisitorCount</td> 151 <td>@item.BeforeYearVisitorCountProportion</td> 152 <td>@item.Ratio</td> 153 <td>@item.YearRatio</td> 154 </tr> 155 } 156 } 157 158 </table> 159 </div> 160 <div style="padding-top:50px;"> 161 <table class="zTable" cellpadding="0" cellspacing="0" style="width:80%;text-align:center; background-color:white;"> 162 <tr> 163 <td colspan="20" style="font-weight:bolder;text-align:center;background-color:#87CEFA;">單品</td> 164 </tr> 165 <tr> 166 <td style="font-weight:bolder;">貨號</td> 167 <td style="font-weight:bolder;">日期</td> 168 <td style="font-weight:bolder;">實際銷售件數</td> 169 <td style="font-weight:bolder;">實際銷售金額</td> 170 <td style="font-weight:bolder;">退貨件數</td> 171 <td style="font-weight:bolder;">退貨金額</td> 172 <td style="font-weight:bolder;">搜索排名</td> 173 <td style="font-weight:bolder;">瀏覽量</td> 174 <td style="font-weight:bolder;">訪客數</td> 175 <td style="font-weight:bolder;">加購人數</td> 176 <td style="font-weight:bolder;">加購率</td> 177 <td style="font-weight:bolder;">下單客戶數</td> 178 <td style="font-weight:bolder;">下單轉化率</td> 179 <td style="font-weight:bolder;">成交客戶數</td> 180 <td style="font-weight:bolder;">成交商品數</td> 181 <td style="font-weight:bolder;">成交轉化率</td> 182 </tr> 183 <tr> 184 @if (singleProductDayOrWeekReports != null) 185 { 186 foreach (var item in singleProductDayOrWeekReports) 187 { 188 <tr> 189 <td style="font-weight:bolder;">@item.StyleNo</td> 190 <td style="font-weight:bolder;">@(item.Time.Value.ToString("yyyy-MM-dd"))</td> 191 <td>@item.RealSaleCount</td> 192 <td>@item.RealSaleAmount</td> 193 <td>@item.ReturnProductCount</td> 194 <td>@item.ReturnProductAmount</td> 195 <td>@item.SearchRanking</td> 196 <td>@item.BrowseVolume</td> 197 <td>@item.VisitorCount</td> 198 <td>@item.AddPurchasePeopleCount</td> 199 <td>@item.AddPurchaseRate</td> 200 <td>@item.OrderCustomerCount</td> 201 <td>@item.OrderConversionRate</td> 202 <td>@item.DealCustomerCount</td> 203 <td>@item.DealProductCount</td> 204 <td>@item.DealConversionRate</td> 205 </tr> 206 } 207 } 208 </table> 209 </div> 210 <div style="padding-top:50px;"> 211 <form id="summaryAndPlan"> 212 <table class="zTable" cellpadding="0" cellspacing="0" style="width:80%;"> 213 <tr> 214 <td class="adminTitle" style="font-weight:bolder;"> 215 總結: 216 </td> 217 <td class="adminData"> 218 <textarea id="Summary" name="Summary" style="width:600px;height:100px;">@(weekReportSummaryAndPlan==null?"":weekReportSummaryAndPlan.Summary.Trim())</textarea> 219 </td> 220 </tr> 221 <tr> 222 <td class="adminTitle" style="font-weight:bolder;"> 223 計划: 224 </td> 225 <td class="adminData"> 226 <textarea id="UpPlan" name="UpPlan" style="width:600px;height:100px;">@(weekReportSummaryAndPlan == null ? "" : weekReportSummaryAndPlan.UpPlan.Trim())</textarea> 227 </td> 228 </tr> 229 <tr> 230 <td class="adminData" colspan="2" style="text-align: center;"> 231 <input type="button" id="confirmPlan" class="k-button" value="確定" /> 232 </td> 233 </tr> 234 </table> 235 </form> 236 </div> 237 </div> 238 <script> 239 $("#confirmPlan").click(function () { 240 if (confirm("確定嗎?")) { 241 var summary =$("#@Html.FieldIdFor(x=>x.Summary)").val(); 242 var plan =$("#@Html.FieldIdFor(x=>x.UpPlan)").val(); 243 $.ajax({ 244 url: "@Url.Action("123", "aa")", 245 data: { "webSiteName":"@webSiteName","summary": summary,"plan":plan,"weekName":"@weekName"}, 246 type: "POST", 247 success: function (result) { 248 if (result.split("|")[0] == "true") { 249 alertBox(result.split("|")[0], result.split("|")[1]); 250 } else { 251 alertBox(result.split("|")[0], result.split("|")[1]); 252 } 253 } 254 }); 255 } 256 }); 257 </script> 258 <script src="~/Scripts/jquery-1.8.2.js"></script> 259 <script src="~/Scripts/html2canvas.min.js"></script> 260 <script src="~/Scripts/bluebird.js"></script> 261 <script type="text/javascript"> 262 $(document).ready(function () { 263 // canvas生成圖片 264 $("#btn").on("click", function () { 265 var getPixelRatio = function (context) { // 獲取設備的PixelRatio 266 var backingStore = context.backingStorePixelRatio || 267 context.webkitBackingStorePixelRatio || 268 context.mozBackingStorePixelRatio || 269 context.msBackingStorePixelRatio || 270 context.oBackingStorePixelRatio || 271 context.backingStorePixelRatio || 0.5; 272 return (window.devicePixelRatio || 0.5) / backingStore; 273 }; 274 //生成的圖片名稱 275 var imgName = "@(webSiteName)@(weekName).jpg"; 276 var shareContent = document.getElementById("imgDiv"); 277 var width = shareContent.offsetWidth; 278 var height = shareContent.offsetHeight; 279 var canvas = document.createElement("canvas"); 280 var context = canvas.getContext('2d'); 281 var scale = getPixelRatio(context); //將canvas的容器擴大PixelRatio倍,再將畫布縮放,將圖像放大PixelRatio倍。 282 canvas.width = width * scale; 283 canvas.height = height * scale; 284 canvas.style.width = width + 'px'; 285 canvas.style.height = height + 'px'; 286 context.scale(scale, scale); 287 288 var opts = { 289 scale: 1, 290 background: '#FFFFFF' 291 }; 292 window.pageYoffset = 0; 293 document.documentElement.scrollTop = 0; 294 document.body.scrollTop = 0; 295 html2canvas(shareContent, opts).then(function (canvas) { 296 context.imageSmoothingEnabled = false; 297 context.webkitImageSmoothingEnabled = false; 298 context.msImageSmoothingEnabled = false; 299 context.imageSmoothingEnabled = false; 300 var dataUrl = canvas.toDataURL('image/jpeg', 1.0); 301 dataURIToBlob(imgName, dataUrl, callback); 302 }); 303 }); 304 }) 305 306 307 // edited from https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#Polyfill 308 var dataURIToBlob = function (imgName, dataURI, callback) { 309 var binStr = atob(dataURI.split(',')[1]), 310 len = binStr.length, 311 arr = new Uint8Array(len); 312 313 for (var i = 0; i < len; i++) { 314 arr[i] = binStr.charCodeAt(i); 315 } 316 317 callback(imgName, new Blob([arr])); 318 } 319 320 var callback = function (imgName, blob) { 321 var triggerDownload = $("<a>").attr("href", URL.createObjectURL(blob)).attr("download", imgName).appendTo("body").on("click", function () { 322 if (navigator.msSaveBlob) { 323 return navigator.msSaveBlob(blob, imgName); 324 } 325 }); 326 triggerDownload[0].click(); 327 triggerDownload.remove(); 328 }; 329 </script>
四 效果圖
五 最后
自己記錄一下,有這方面的需求,大家可以借鑒一下。