ASP.NET中应用Excel:(10)在客户端生成HTML表格[修正]

前面描述了如何在服务器端生成HTML表格,本节就讲述如何在客户端完成同样的工作。在客户端实现这个功能,需要用到ScriptMethod方法,将XmlDocument返回到客户端,客户端使用JavaScript脚本来完成表格的渲染工作。

先实现服务器端的WebService,假定为ReadDataService.asmx。其实现大致如下:

using System.Xml;

using System.Xml;

...


/// <summary>

/// Summary description for MyService

/// </summary>

[WebService(Namespace = "http://tempuri.org/")]

[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

[ScriptService]

public class ReadDataService: System.Web.Services.WebService 
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Xml)]
    public XmlDocument read(string excelFile) // 这里直接使用文件名作为参数,实际应用中应该使用其它参数,如id之类,否则可能有安全上的问题
    {
        XmlDocument xml = new XmlDocument();

        xml.LoadXml("<?xml version=/"1.0/" encoding=/"utf-8/" ?><Data></Data>");

        // 填充xml的过程略

        ...

        return xml; // 结果

    }

    ...
}

在页面上还需要加入对WebService的引用,也可以加到MasterPage中:

<ajaxToolkit:ToolkitScriptManager ID="ScriptManager1" runat="server" >
    <Services>
            <asp:ServiceReference  Path="ReadDataService.asmx" />
        </Services>
</ajaxToolkit:ToolkitScriptManager>

在客户端这样通过JavaScript脚本调用WebService的方法:

ReadDataService.read(onReadDataSucceeded, onReadDataFailed, 'xmlDocument');

onReadDataSucceeded和onReadDataFailed分别处理调用成功和失败事件。我们在成功时生成表格,失败则给出提示:

// result是服务器返回的结果
// context是指定的上下文,这里是'xmlDocument'
// methodName则是read,我们的ReadDataService.read方法的名字
function onReadDataSucceeded(result, context, methodName)
{
    readTicks = getMilliseconds() - readTicks; // 这个时间现在在10秒内,在我的示例中大致为7.3-7.5秒之间
    
    //alert('Time consumption:' + (readTicks / 1000.0) + ' seconds');
    
    if ( document.all ) // IE
    {
        for(var sheet_idx = 0; sheet_idx < result.documentElement.childNodes.length; sheet_idx++) // 遍历工作表
        {
            var sheet_node = result.documentElement.childNodes[sheet_idx]; // 工作表节点
            
            var _rowNum = 1, // 工作表行列数
                _colNum = 1,
                sheetName = ''; // 工作表名 
                
            var table = document.createElement('TABLE'); // 创建新表
            
            table.id = 'Sheet_' + sheet_idx; // 表名
            
            // 设置单元格样式
            table.style.borderCollapse = 'collapse';
            table.style.tableLayout = 'fixed';
            table.style.border = '1px solid black';
            
            // 设置单元格属性
            table.cellPadding = 0;
            table.cellSpacing = 0;
            
            for(var attr_idx = 0; attr_idx < sheet_node.attributes.length; attr_idx++)
            {                                    
                var attr = sheet_node.attributes[attr_idx];
                
                switch(attr.nodeName)
                {
                case 'name':    sheetName = attr.nodeValue; break;
                case 'width':   table.style.width = attr.nodeValue + 'pt'; break; // 宽度
                case 'row':     _rowNum = parseInt(attr.nodeValue); break; // 行,列数
                case 'col':     _colNum = parseInt(attr.nodeValue); break;
                }
            }
            
            // 将工作表添加到document
            if ( document.sheet )
                document.sheet[document.sheet] = { 'table': table.id, 'name': sheetName };
            else
                document.sheet =  [{ 'table': table.id, 'name': sheetName }];
            
            // 工作表名称
            var sheetNameRow = table.insertRow();
            
            var sheetNameCell = sheetNameRow.insertCell();
            
            initHeaderCell(sheetNameCell);
            
            sheetNameCell.colSpan = _colNum + 1;
            sheetNameCell.innerText = sheetName;
            sheetNameCell.style.width = table.style.width;
            
            
            // 添加列头
            var colHeaderRow = table.insertRow();
            
            for(var col_idx = 0; col_idx <= _colNum; col_idx++ )
            {
                var cell = colHeaderRow.insertCell(); //col_idx);
                
                if ( col_idx > 0 )
                    cell.innerText = getColLabel(col_idx);
                else
                    cell.innerText = ' '; // 第一个单元格!
                    
                initHeaderCell(cell);
            }
            
            for(var row_idx = 0; row_idx < sheet_node.childNodes.length; row_idx++ ) // 遍历行
            {
                var row = table.insertRow() // row_idx + 1); // 插入行
                
                {// 插入行标头
                    var rowHeaderCell = row.insertCell(); //0);
                
                    initHeaderCell(rowHeaderCell);
                
                    rowHeaderCell.innerText = row_idx + 1; //row.rowIndex;
                }
                
                var row_node = sheet_node.childNodes[row_idx]; // 行节点
                
                for(var attr_idx = 0; attr_idx < row_node.attributes.length; attr_idx++ ) // 遍历属性,设置行高
                {
                    var attr = row_node.attributes[attr_idx]; // 获取行属性
                    
                    switch(attr.nodeName)
                    {
                    case "height": row.height = attr.nodeValue; break; // 高度
                    }
                }
                
                if ( row_node.childNodes.length == 0 ) // 没有单元格,是一个空行
                {
                    for(var i = 1; i <= _colNum; i++ ) // 插入空单元格
                    {
                        initEmptyCell(row.insertCell()); //i));
                    }
                }
                else
                for(var cell_idx = 0; cell_idx < row_node.childNodes.length; cell_idx++ ) // 遍历列
                {
                    var cell_node = row_node.childNodes[cell_idx]; // 单元格节点
                    var prev_cell_node = cell_node.previousSibling; // 前一个节点
                    var cellProp = { // 单元格属性
                                'row': 0,
                                'col': 0,
                                'rowspan': 1,
                                'colspan': 1,
                                'hasFormula': false,
                                'formula': '',
                                'value2': '',
                                'weight': '',
                                'height': '',
                                'font-family': '',
                                'font-size': '',
                                'font-color': '',
                                'font-bold': false,
                                'font-italic': false,
                                'font-strikethrough': false,
                                'align': '',
                                'valign': ''
                            };
                    // 获取单元格属性
                    for(var attr_idx = 0; attr_idx < cell_node.attributes.length; attr_idx++ )
                    {
                        var attr = cell_node.attributes[attr_idx];
                        
                        cellProp[attr.nodeName] = attr.nodeValue;
                    }
                    
                    // 从XML解析出来的数据会成为字符串,因此需要修正为number,否则下文的补完计划会出错
                    cellProp.col = parseInt(cellProp.col);
                    cellProp.rowspan = parseInt(cellProp.rowspan);
                    cellProp.colspan = parseInt(cellProp.colspan);
                    
                    if ( prev_cell_node ) // 如果前一个节点存在,可能需要补完中间的空白
                    {
                        var prevColIdx = 0, // 前一个节点的单元号和
                            prevColSpan = 1;

 

                        for(var attr_idx = 0; attr_idx <  prev_cell_node.attributes.length; attr_idx++ ) // 获取前一单元格的属性                         {                             var attr = prev_cell_node.attributes[attr_idx];                                                         switch(attr.nodeName)                             {                             case 'col' : prevColIdx = parseInt(attr.nodeValue); break; // 列号                             case 'colspan' : prevColSpan = parseInt(attr.nodeValue); break; // 列跨度                             }                         }                                                 if (prevColIdx + prevColSpan < cellProp.col) // 如果中间有空,则插入                         {                             for ( var i = prevColIdx + prevColSpan; i < cellProp.col; i++)                             {                                 initEmptyCell(row.insertCell()); //i)); // 补完空洞                             }                         }                     }                     else                     {                         if ( cellProp.col > 1 ) // 如果不是第1个单元格(从0开始为列标头),需要补完                         {                             for ( var i = 1; i < cellProp.col; i++ )                                 initEmptyCell(row.insertCell(i)); // 补完空洞                         }                     }                                         // 插入单元格                     var cell = row.insertCell();                                         // 设置属性                     cell.align = cellProp.align;                     cell.valign = cellProp.valign;                     cell.width = cellProp.width;                     cell.height = cellProp.height;                     cell.style.color = cellProp['font-color'];                     cell.style.fontFamily = cellProp['font-family'];                     cell.style.fontSize = cellProp['font-size'];                     cell.style.fontWeight = cellProp['font-bold'] == 'true' ? 'bold' : '';                     cell.style.border = '1px solid black';                     cell.colSpan = cellProp.colspan;                     cell._rowspan = cellProp.rowspan;                                         // 设置数据域                     cell.hasFormula = cellProp.hasFormula;                     cell.formula = cellProp.formula;                     cell.dataField = cell.innerText = cellProp.value2;                                         // 如果没有后续节点,表明是最后一个单元格,此时需要补完,使之具有_colNum个列                     if (cell_node.nextSibling == null && cellProp.col + cellProp.colspan <= _colNum)                     {                         for ( var i = cellProp.col + cellProp.colspan; i <= _colNum; i++ )                             initEmptyCell(row.insertCell()); //i)); // 插入空单元格                     }                 } // for cell             } // for row                         setAllCellTip(table);                         document.body.appendChild(table);         } // for sheet     }     else     {   // fireFox         // 留待同学课后作业     } }

 

function onReadDataFailed(error) // 提示处理错误 {     var stackTrace = error.get_stackTrace();     var message = error.get_message();     var statusCode = error.get_statusCode();     var exceptionType = error.get_exceptionType();     var timedout = error.get_timedOut();         // Display the error.     alert( "Stack Trace: " + stackTrace + "<br/>" +               "Service Error: " + message + "<br/>" +               "Status Code: " + statusCode + "<br/>" +               "Exception Type: " + exceptionType + "<br/>" +               "Timedout: " + timedout);}

至此为至,客户端生成表格的工作也完成了。

 

 

你可能感兴趣的:(html,工作,webservice,Excel,table,asp.net)