11.2 报表文件
报表最终的存储格式是 XML 格式，您可以将报表保存在本地，也可以保存到服务器。
将报表保存到服务器，通常是通过 js 调用 GetFileXML 函数实现的:

     var xml = AF.func("GetFileXML", "");

上例中的这个名为"xml"的变量，其内容是一个大串，您可以通过 ajax 将它 POST 给应用服务器，让应用服务器去解决最终的存储。
至于如何在 html 页面上安排具体的上传功能，可以有如下几种方案:
方案1：在页面中增加一个“上传”的按钮，在按钮的 onClick 事件中调用 GetFileXML( ) 函数，将 XML 串 POST 给服务器;
方案2：监听工具条上的“保存”按钮： 在OnEvent( ) 事件函数中处理“Saved”事件, 在事件中执行 GetFileXML( ) 函数，将 XML 串 POST 给服务器;
报表组件从1.0.81.0版开始，支持以 zip 方式压缩的 XML 文件了，该支持包括 2 个方面：
1.Build( ) 函数能直接读入 zip 二进制文件或 http 流，例如 http://mysite/reports/abc1.zip , 当然也支持动态的 aspx/jsp 的 URL, 只要这个 URL 返回 zip 文件的纯二进制内容即可;
2.将报表 XML 压缩成 zip 文件，并以 http POST 将二进制发送给服务器, 具体的实现方法如下：
步骤1. 通过 callfunc 函数调用 104 功能号 (104功能号的说明在"4.工具条功能号"中)，生成当前报表的 zip 文件，如：

    AF.func("callfunc", "104 \r\n c:\\report3.zip");

上例中，文件名是写死的，不太符合实际开发习惯，所以建议使用全局缓存函数 CacheDirUtility，该函数能动态生成唯一的文件名，将程序修改成如下：

    var filename = AF.func("CacheDirUtility", "isCreateTempFile=true; ext=zip");
    AF.func("callfunc", "104 \r\n" + filename);

步骤2. 通过全局函数 HttpPostLocalFile 将该文件上传，如：

    AF.func("HttpPostLocalFile", "http://mysite/reports/rec.aspx?name=rpt1&org=23 \r\n" + filename);

当然，上面的这个 "rec.aspx" 接收程序得由您自己写，由您决定把 Http Body 中的二进制内容写到服务器文件或存入数据库.
11.3 异步计算
通过API函数Calc( )，或者工具条上的“计算”按钮，可以触发报表的填数计算。如果计算过程比较漫长(例如后端计算性能、数据量等因素导致)，浏览器表现为锁死, 甚至无法切换Tab选项卡，必须要等到整个计算过程结束才能恢复可操作。
硕正报表从1.0.66.0版开始，增加了异步计算功能，解决了计算过程中的浏览器僵死问题。
如果Calc( )函数的参数设为 "mode=asynch", 就表示采用异步计算模式，计算过程被安排在另一个线程中，而该函数则立即返回，当计算真正结束时，报表组件会通过“Calced”事件通知浏览器。
从启动异步计算，到发出“Calced”事件之间，你不应该调用该控件的任何API函数，否则异步将无意义。
工具条上的计算按钮()，也是采用异步计算的.
11.4 自定义打印纸
在打印设置对话框中，有自定义打印纸尺寸的选项按钮，关于自定义打印纸这个功能，有必要在此分析一下其原理。
首先，硕正报表的打印是基于Windows的常规API打印的，也就是说是基于页式打印，不可能去调用具体的打印机驱动程序做诸如逐行即打即停的功能的。
这个“页式打印”就是以打印纸为单位，每完成一个页任务，打印机就应该吐出一张打印纸来，所以，对于大多数激光、喷墨打印机而言，自定义打印纸恐怕是毫无意义的。
所以，通常所说的“自定义打印纸”是用于针式打印机的，针式打印机一般都允许自定义打印纸。
如果在自定义打印纸过程中出现如下错误：
有2种可能的原因：
原因1 - 所选的打印机本身就不支持自定义纸张；
原因2 - 操作系统没有给IE控件足够的权限，具体的解决办法是在IE的“Internet选项”的“安全”中降低安全等级，待打印纸自定义完毕，再恢复安全等级；
如果权限问题总是无法解决，那么建议您到“控制面板”- “设备和打印机”中去手动设置，事实上，用硕正控件设置自定义打印纸和手动自定义打印纸是没区别的。
一旦打印纸自定义成功，那么在“打印纸”的下拉选择框中，就会自动包含有刚才自定义的那种打印纸，这个自定义信息是登记在操作系统注册表中的，一次定义好后，今后都能用。
由于自定义打印纸是和具体的打印机相关联的，所以还建议您进一步勾选对话框中的“认定使用这台打印机”的选项，然后保存模板。
最后，我们谈谈自定义打印纸的另一个常见话题：打印模板发布后，网络上其它用户都需要逐个去设置自定义打印纸吗？
首先，我们模板中是包含了自定义打印纸的完整的自定义信息的，比如纸名、设定的尺寸。当其它用户打开该模板后，报表控件首先会检查本地是否安装了同样的打印机，如果能找到同名的打印机，那么它会进一步去检查是否已经有这种自定义打印纸了，如果没有，它会自动创建的。所以这个过程是自动的。
当然，在自动创建的过程中，也同样可能遇到权限不足的问题，遇到此问题，您只好按上面的解决办法手工去解决了。
11.5 条形码
报表中的单元格和文本框都可以作为条形码显示，操作方法为：
1.在工具箱中切换到“显示格式”选项卡;
2.将数据类型改成“字符型”;
3."其它显示形式" 选 "以条形码显示";
4.条形码更多的选项在 "条形码选项";
11.6 内嵌树列表(Treelist)
从1.0.72.0版开始，工具条中增加了树列表的图标，您可以把一个树列表直接加入到报表中。在上报模式中，树列表也能够以“指标”的方式被预先定义在指标库中。
内嵌树列表只有在运行时(RunTime)才是真正可用的。 而在设计时(DesignTime), 树列表始终处于不活动的状态，您看到的树列表只是一幅图，供您拖拽布局：
内嵌树列表 和 普通的页面中的树列表，完全是同一种东西，但是访问报表中的内嵌树列表，通常是先获得树列表的句柄，然后以扩展函数方式调用，如下例：

    //先获得树列表的句柄 (注："m010" 是树列表的别名)
    var h = AF.func("GetHandle", "m010");

    //以扩展方式执行该树列表的函数
    var xml = AF.func(h + "GetChangedXML", "level=0;isIgnoreChange=true");

此外，也可以采用另一种更简洁的写法：

    var xml = AF.func("m010.GetChangedXML", "level=0;isIgnoreChange=true");  //"m010" 是树列表的别名

通过上述的这2种扩展方式，您可以访问树列表的几乎所有函数。
在运行时(RunTime), 报表内嵌的树列表能向页面抛出 OnEvent(id, Event, p1, p2, p3, p4) 事件，但是和普通的页面树列表有一个差别：Event(事件名)前面带有树列表的别名，例如:

    function OnEvent(id, Event, p1, p2, p3, p4)
    {
     if(id=='AF') { 	//id不变
       //树列表的双击事件，其中 "m010" 是触发了事件的树列表的别名
       if(Event == "m010.DblClicked") {
        ...
       }
     }
    }