9.3.上报汇总模版

  硕正报表从1.0.99.0开始,支持上报汇总模式(在线演示第八部分 “报表上传汇总”)的移动端实现了,这意味着在手机上也能输入了,且数据格式和PC端无差别、上报的后端接收程序也完全通用.
  调用 105 功能号转换成 html 的过程,比普通查询用的报表略为复杂: 它必须依赖模版进行.
  手机上报的在线演示例子在 “5.体验五” 、 “6.体验六” 中,该例子后端的程序和模版包是:uploadmobile.zip,您解开看下,下面将针对这个包展开说明。

9.3.1 模版分析

  包中的模版文件是 template_upload.txt:
<!DOCTYPE html>
<html>
 <head>
  <meta name="viewport" content="width=<!--SUPCAN_REPORT_MAXWidth-->, initial-scale=1, minimum-scale=0.5">
  <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
  <script src="../uploadxml.js"></script>
  <script>
   var SupcanUploadURL = "<!--SUPCAN_REPORT_UploadURL-->";
   var SupcanWorksheetName = "<!--SUPCAN_REPORT_WorkSheetName-->";
   <!--SUPCAN_REPORT_JS-->
  </script>
  <style>
   <!--SUPCAN_REPORT_STYLE prefix="dx"-->
   input{ width: 95%; margin: 1; padding: 0; }
   select{ width: 95%; margin: 1; padding: 0; }
  </style>
 </head>
 <body>
  <!--SUPCAN_REPORT_dMain-->
  <div style="text-align:center">
   <input type="button" id="idok" value=" 提交 " style="width:100px; height:28px">
  </div>
 </body>
</html>
  可见,模版是基于 HTML5、借助 jquery 实现的.
  第4行,用到了占位符 <!--SUPCAN_REPORT_MAXWidth-->,viewport 没有使用 HTML5 默认的 device-width, 相当于告诉手机浏览器,当报表宽度超宽时自动伸展显示, 当然你也可以试试改回 device-width, 看看效果会怎样。
  第8行的占位符 <!--SUPCAN_REPORT_UploadURL--> 将被替换成后端 aspx 中规定的上报目的地 URL。
  这个模版比较简单,但引用的 uploadxml.js 稍为复杂,这个 js 文件是硕正提供的,其功能是处理下拉、遍历 html 元素生成上报的 XML 串, 部署时请注意相对URL的位置: 它是相对于最终生成的 html,而不是这个模版的位置。
  你可以先直接使用这个模版,并对其做些样式的美化润色工作.

9.3.2 uploadxml.js分析

 ...
 //按钮事件: ajax 上报 XML 数据
 $("#idok").click(function() {
  var xml = Supcan_genXML();
  $.ajax({url: SupcanUploadURL,  data: xml,  type: 'POST',  contentType: "text/xml",  dataType: "text",
   success : function(data) {
    if(data == "")
     alert("申请成功!	");
    else {  //验证未通过
     var cellname = "";
     var index = data.indexOf(":");
     if(index != -1) {
       cellname = data.substr(0, index);
       data = data.substring(index + 1);
     }
     alert(data);
     //焦点定位
     if(cellname != null) $("[cellname='" +cellname+ "']").focus().select();
    }
   },
   error : function(xhr, ajaxOptions, thrownError) { alert("提交失败: " + thrownError + "状态码: " + xhr.status); }
  });
 });...
  这是点击 “提交” 触发的事件,这个部分源码类似于PC端开发中的 GetUploadXML 函数功能。
  第4行调用了 Supcan_genXML() 函数获取完整的XML, 下面部分是 ajax 上传的实现.
  第5行的变量 SupcanUploadURL 值来自模版的占位符.
  下方代码是处理下拉、生成XML串的一些细节,请自行分析.

9.3.3 C#源码分析

  在此分析 up.aspx 中的2个功能:动态转换功能,和收集上报XML并对其验证的功能。
  动态转换功能和前面的例子相比,基本类似,只是需要指定模版文件和 uploadURL 参数:
 //创建报表服务
 ...
 //生成临时文件,同时删除1小时前的垃圾文件
 String TempFilename = dll.func("CacheDirUtility", "isCreateTempFile=true;ext=htm; DeleteEarlierFile=1h");
 
 //指定模版文件, 它位于当前目录下
 String TemplateFilename = Server.MapPath("template_upload.txt");
 
 //规定 uploadURL 参数: html 的 ajax 上传数据的URL,它将替换模版中的 <!--SUPCAN_REPORT_UploadURL--> 占位符
 String uploadURL = BaseDir + "dotnet/up.aspx?func=33&uid=" +uid;
 
 //打开报表
 dll.func("build", "report/uploadmobile.xml");
 
 //转换
 dll.func("callfunc", "105\r\n type=htm; Template=" +TemplateFilename+ "; uploadURL=" + uploadURL + "; filename=" + TempFilename);
 ...

  收集上报XML并对其验证的功能, 也集成在这个 aspx 文件中,用 URL 中的 func 参数做条件判断:
 //打开报表
 dll.func("build", "report/uploadmobile.xml");
 
 //分支:功能号33,请求验证
 if(pageFunc == "33") {
  //取得 ajax 上传的 XML 串,它位于 http body 中
  Stream postData = Request.InputStream;
  StreamReader sr = new StreamReader(postData);
  String xml= sr.ReadToEnd();
  sr.Close();
  
  //验证
  dll.func("RebuildTabOrder", "");
  dll.func("SetUploadXML", xml + "\r\n autoCalc=none");
  String Err = dll.func("callfunc", "50 \r\n isReport=one");	//验证, 只需要返回一条错误
  //关闭报表服务
  dll.CloseService();
  Response.Write(Err);  //写错误信息到 Response, Err为空串表示通过验证
  Response.End();
  return;
 }
  在实际使用中,如果验证通过了,那么下一步通常就是对该XML进行解析,并分离出各个数据将其保存到数据库中。本例略去了这个过程。