0

嗨,我正在使用 jQuery 和 Microsoft ASP.net 2.0、C# 作为服务器端在 Web 上开发富客户端 UI,我基本上有 2 个问题,列在下面

  1. 为此,我正在使用 HTMLTextWriter 和 StringWriter 类库。我在互联网上搜索并从各种教程和/或提示中学到了什么正在传输数据,并且在那部分一切正常,但是在将 html 转换为 excel 电子表格时,它还将下载页面的 html 标记附加到 excel 标记中。
  2. 当我在输出数据后调用 Response.Close() 时,出现连接中止错误。

这是代码片段

公共 StringWriter getHTMLStream(){

            输出 = 新的 StringWriter();
            htmlWriter = new HtmlTextWriter(输出);
            字符串 html=@"
      表 {mso-displayed-decimal-separator:'\.'; mso-displayed-thousand-separator:'\,';}.xlGeneral {padding-top:1px; 填充右:1px;填充左:1px;mso忽略:填充;颜色:窗口文本;字体大小:10.0pt;字体粗细:400;字体样式:正常;文字装饰:无;字体系列:宋体;mso 通用字体系列:自动;mso字体字符集:0;mso 数字格式:一般;文本对齐:一般;垂直对齐:底部;mso-背景源:自动;mso 模式:自动;空白:nowrap;}“;
            html+=""+this.headerName+"-"+this.vehicleName+"";
            totalCols = (this.reportOrientation == "Horiz")?data.Columns.Count:2;
            if (this.reportOrientation == "Horiz")
            {
                html+="";
                // 添加标题列
                foreach(this.data.Columns 中的 DataColumn colName)
                {
                    html+=""+colName.ColumnName.Trim()+"";
                }
                html+="";

                // 现在添加数据
                foreach(this.data.Rows 中的 DataRow dr)
                {
                    html+="";
                    foreach(dr.ItemArray 中的字符串 colData)
                    {
                        html+=""+colData+"";
                    }
                    html+="";
                }
            }
            别的
            {
                // 获取列
                colsArr = 新字符串[this.data.Columns.Count];
                int colCounter = 0;
                foreach(this.data.Columns 中的 DataColumn colName)
                {
                    colsArr[colCounter] = colName.ColumnName;
                    colCounter++;
                }
                //tableHeads = arrayToString(colsArr);
                // 获取字符串数组中的行数据
                rowArr = 新字符串[this.data.Columns.Count];

                foreach(this.data.Rows 中的 DataRow dr)
                {
                    colCounter = 0;
                    foreach(dr.ItemArray 中的字符串 col)
                    {
                        rowArr[colCounter] = col;
                        colCounter++;
                    }
                }
                //tableHeads = arrayToString(colsArr);
                // 添加 PDF 表格单元格
                for (int i = 0; i "+colsArr[i].Trim()+""+rowArr[i].Trim()+"";
                }

            }
            html+= "";
            htmlWriter.Write(html);
            返回输出;
        }

        私有字符串arrayToString(字符串[]数组){
            字符串结果 = string.Join(",", 数组);
            结果 = result.Substring(0, result.Length - 1);
            返回结果;
        }
    }

这就是我访问它的方式

响应。清除();
            createHTML speedXLS = new createHTML("车速报告", "Horiz", vehicleName, speedDT);
            Response.ContentType = "应用程序/vnd.xls";
            Response.AddHeader("content-disposition", "attachment;filename=VSpeedReport-" + vehicleName + ".xls");
            Response.Write(speedXLS.getHTMLStream().ToString());
            //Response.Close();

这是附加到我的 excel 标记的下载页面标记旁边想要的 xls 标记的内容。如何告诉服务器不要在响应正文中附加页面的标记? **

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head><title>

    </title></head>
    <body>
        <form name="form1" method="post" action="downloadData.aspx?reportType=speed&amp;value=1&amp;valUnit=Miles&amp;reqType=XLS&amp;selVehicle=GTA02&amp;Email=gps%40gtalimo.com&amp;startDate=2012-4-27+23%3a21%3a00&amp;endDate=2012-4-28+01%3a21%3a00&amp;vehicleName=GTA+07" id="form1">
    <div>
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTE2MTY2ODcyMjlkZKkkaxju0wAdoc1rGUJiLkzjS9eU" />
    </div>

        <div>

        </div>
        </form>
    </body>
    </html>

** 请提出意见或建议!谢谢!

4

2 回答 2

1

生成 html 表并欺骗浏览器在 excel 中显示它并不是将数据导出到 excel 的最佳方法。这是一个黑客而不是解决方案,而且 IMO 什么时候停止工作只是时间问题,可能是在下一个 excel 版本中,或者因为某些病毒/反恶意软件/任何检测到您正在发送带有错误标题的内容,并且 excel 2007/2010 已经警告用户关于那个。

**更新:**在我看来,最好的方法是使用可以生成真正的 excel 文件的 3rd 方 excel 库,然后浏览器将打开 excel,并且内容匹配标题。并且有非常好的开源库,我真的不明白为什么不应该使用它们。

NPOI (xls) 或/和EPPlus (xlsx)

因此,如果您仍然想在不使用 CSV 格式的情况下执行此操作,并且第 3 方库使用 CSV 格式,请在此处查看将 DataTable 导出为 CSV 的示例:

将 DataTable 转换为 CSV 流

替代方法是使用 excel 模式导出到 XML。这是代码:

public static MemoryStream DataSetToExcelXml(DataSet ADataset)
{
  MemoryStream result = new MemoryStream();
  XmlDataDocument doc = new XmlDataDocument(ADataset);
  XslCompiledTransform trans = new XslCompiledTransform();
  XmlDocument xmlDoc = new XmlDocument();
  Stream shema = Assembly.GetExecutingAssembly().GetManifestResourceStream("ResPathToExcelSheet.xsl");
  xmlDoc.Load(shema);
  trans.Load(xmlDoc);
  trans.Transform(doc, null, result);
  return result;
}

架构

<xsl:stylesheet version="1.0"
    xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 xmlns:user="urn:my-scripts"
 xmlns:o="urn:schemas-microsoft-com:office:office"
 xmlns:x="urn:schemas-microsoft-com:office:excel"
 xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet" >  
<xsl:template match="/">
  <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:o="urn:schemas-microsoft-com:office:office"
    xmlns:x="urn:schemas-microsoft-com:office:excel"
    xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
    xmlns:html="http://www.w3.org/TR/REC-html40">
    <xsl:apply-templates/>
  </Workbook>
</xsl:template>
<xsl:template match="/*">
  <Worksheet>
  <xsl:attribute name="ss:Name">
  <xsl:value-of select="local-name(/*/*)"/>
  </xsl:attribute>
    <Table x:FullColumns="1" x:FullRows="1">
      <Row>
        <xsl:for-each select="*[position() = 1]/*">
          <Cell><Data ss:Type="String">
          <xsl:value-of select="local-name()"/>
          </Data></Cell>
        </xsl:for-each>
      </Row>
      <xsl:apply-templates/>
    </Table>
  </Worksheet>
</xsl:template>
<xsl:template match="/*/*">
  <Row>
    <xsl:apply-templates/>
  </Row>
</xsl:template>
<xsl:template match="/*/*/*">
  <Cell><Data ss:Type="String">
    <xsl:value-of select="."/>
  </Data></Cell>
</xsl:template>
</xsl:stylesheet>
于 2012-04-28T07:10:35.347 回答
1

1.代替

       **strong text** Response.Clear();
createHTML speedXLS = new createHTML("Vehicle Speed Report", "Horiz", vehicleName, speedDT);
Response.ContentType = "application/vnd.xls";
Response.AddHeader("content-disposition", "attachment;filename=VSpeedReport-" + vehicleName + ".xls");
Response.Write(speedXLS.getHTMLStream().ToString());

采用

 **Response.Buffer = true;**

   createHTML speedXLS = new createHTML("Vehicle Speed Report", "Horiz", vehicleName, speedDT);
        Response.ContentType = "application/vnd.xls";
        Response.AddHeader("content-disposition", "attachment;filename=VSpeedReport-" + vehicleName + ".xls");
        Response.Write(speedXLS.getHTMLStream().ToString());
  1. 当您使用流类时,请使用“使用”语句。
于 2012-04-28T07:14:42.733 回答