最近的项目中有一个地图打印的功能需求,将地图底图和叠加的图层服务输出成图片保存。
实现该功能通常有两钟方法,一是利用ArcGIS API For JS提供的PrintTask接口(https://developers.arcgis.com/javascript/3/jssamples/#search/PrintTask),但是该方法适用于ArcGIS Server发布的图层服务,如果底图为天地图、高德底图等,则输出为空白;第二种则是利用html2canvas插件进行通用的屏幕截图输出,这种方法适用于各种类型的底图服务。下面实现的地图打印功能也是基于html2canvas插件实现的。
实现的过程也是比较简单的,直接贴代码了。
html2canvas($("div.map-container"), {
useCORS: true,
imageTimeout:0,
onrendered: function (canvas) {
//将长字符分段传输
var imgBase64Str = canvas.toDataURL(); // 获取生成的图片的url
//转到后台生成图片
$.ajax({
type: "POST",
url: $tools.getServerBase() + "FileTool/createImgByBase64",
dataType: 'json',
data: {
base64Str: imgBase64Str
},
success: function (resultObj) {
if (resultObj.code == '1') window.open($tools.getServerBase() + resultObj.path);
else alert("截屏出错!" + resultObj.message);
unloading();
},
error: function () {
unloading();
}
});
}
});
public string createImgByBase64()
{
string path = "";
Dictionary<string,string> resultObj = new Dictionary<string,string>();
try
{
string folder = AppDomain.CurrentDomain.BaseDirectory + "output";
string savePath = folder + @"\\ouput.jpg";
string req = Request["base64Str"].Replace("data:image/png;base64,", "");
byte[] arr = Convert.FromBase64String(req);
MemoryStream ms = new MemoryStream(arr);
Bitmap bmp = new Bitmap(ms);
if (!System.IO.Directory.Exists(folder)) System.IO.Directory.CreateDirectory(folder);
bmp.Save(savePath, System.Drawing.Imaging.ImageFormat.Jpeg);
ms.Close();
path = "output//ouput.jpg";
resultObj.Add("code", "1");
resultObj.Add("path", path);
}
catch (Exception ex)
{
resultObj.Add("code", "0");
resultObj.Add("message", ex.Message);
}
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
string s = jsonSerializer.Serialize(resultObj);
return s;
}
在实现功能过程中遇到一些问题,一是直接在前端利用a标签进行截图下载出现了问题,后面转为将base64字符串传到后台生成图片路径返回到前端,这时候遇到url字符串过长的问题,需要在webConfig中进行以下设置:
<system.web>
<authentication mode="None"/>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2" maxUrlLength="10999" maxQueryStringLength="2097151" maxRequestLength="10000" useFullyQualifiedRedirectUrl="true"/>
</system.web>
<security>
<requestFiltering>
<requestLimits maxUrl="10999" maxQueryString="2097151" />
</requestFiltering>
</security>