ASP.NETでのExcelファイルの生成[終了]


99

ASP.NETアプリ(VB.NETコードビハインド)にセクションを追加しようとしています。これにより、ユーザーはデータをExcelファイルとして返され、データベースデータに基づいて生成されます。これにはいくつかの方法がありますが、それぞれに独自の欠点があります。どのようにデータ返しますか?私はできる限りクリーンでわかりやすいものを探しています。


回答:


131

CSV

長所:

  • シンプルな

短所:

  • 他のロケールや別のExcel構成(リスト区切りなど)では機能しない可能性があります
  • 書式設定、数式などは適用できません

HTML

長所:

  • まだかなりシンプル
  • シンプルなフォーマットと数式をサポート

短所:

  • xlsとしてファイルに名前を付ける必要があります。Excelは、ネイティブでないExcelファイルを開くことについて警告する場合があります。
  • ワークブックごとに1つのワークシート

OpenXML(Office 2007 .XLSX)

長所:

  • ネイティブExcel形式
  • すべてのExcel機能をサポート
  • Excelのインストールコピーを必要としない
  • ピボットテーブルを生成できます
  • オープンソースプロジェクトEPPlusを使用して生成できます

短所:

  • Excel 2007以外では制限された互換性(最近は問題にならないはずです)
  • サードパーティのコンポーネントを使用していない限り複雑

SpreadSheetML(オープンフォーマットXML)

長所:

  • ネイティブExcel形式と比較してシンプル
  • ほとんどのExcel機能をサポート:書式設定、スタイル、数式、ブックご​​とに複数のシート
  • Excelを使用するためにインストールする必要はありません
  • サードパーティのライブラリは必要ありません-xmlを書き出すだけです
  • ドキュメントはExcel XP / 2003/2007で開くことができます

短所:

  • 適切なドキュメントがない
  • 古いバージョンのExcel(2000より前)ではサポートされていません
  • 書き込み専用。これを開いてExcelから変更を加えると、ネイティブExcelに変換されます。

XLS(サードパーティコンポーネントにより生成)

長所:

  • すべてのフォーマット、数式などを含むネイティブExcelファイルを生成します。

短所:

  • 費用がかかる
  • 依存関係を追加する

COM相互運用

長所:

  • ネイティブMicrosoftライブラリを使用
  • ネイティブドキュメントのサポートを読む

短所:

  • 非常に遅い
  • 依存関係/バージョン一致の問題
  • 読み取り時のWeb使用の同時実行性/データ整合性の問題
  • 非常に遅い
  • Web使用のスケーリングの問題(同時実行性とは異なります):サーバー上に重いExcelアプリのインスタンスを多数作成する必要があります
  • Windowsが必要
  • 遅いと言った?

1
SpreadsheetMLで言及されている「書き込み専用」制約は、ExcelファイルをSpreadsheetMLとして保存できるので、完全に問題になるわけではありません。
ブライアン、

1
SpreadsheetMLで大きなファイルを作成すると、Excel 2003がクラッシュする場合があります。それを信用しないでください:/
ブライアン

2
Office 2002および2003では、SpreadsheetMLファイルに正常に保存できます。別名で保存する必要はありません。SpreadsheetMLは、マクロ、グラフ、グラフィックス、およびOffice 2007の新機能(たとえば、3つ以上の条件付きフォーマット)を含むその他のいくつかのオッズとエンドを保存できません。XMLは冗長であるため、サーバーから送信する前にSpreadsheetMLを圧縮すると(SharpZipLibの使用はオプションです)、ダウンロード時間が短縮されます。実際、OpenXMLはいずれにしてもZIPコンテナーに格納されていることを述べておく必要があります。@ブライアン:私は、50〜100 MBの範囲の複雑なSpreadsheetMLをクラッシュの問題なしに毎日使用しています。
richardtallent 2009

大量のデータをエクスポートする必要がある可能性がある場合は、CSVとしてエクスポートする必要があります。SpreadsheetMLとは別に、他の形式のいずれかでパフォーマンスの高いソリューションを作成することは困難です。HTMLは効率的に読み書きできますが、役立つためには、ユーザー側でさらに仕様を指定する必要があります。HTMLとSpreadsheetMLの両方には、ブライアンがコメントで述べているように、大きなファイルに関する他の問題があります。したがって、CSVを使用した単純なデータエクスポートスティックが必要な場合は、
JohannesH

2
@pomarc:簡単かもしれませんが、きれいではありません。ユーザーはExcelファイルを望んでおり、偽の拡張子が付いたHTMLファイルを提供します。
ハインツィ

38

データをhtmlテーブルセルとして出力し、その上にa .xlsまたは.xlsx拡張を貼り付けることができます。Excelは、データをネイティブドキュメントのように開きます。このように、限られた書式設定や数式の計算を行うこともできるため、CSVよりもはるかに強力です。また、htmlテーブルを出力することは、ASP.NetのようなWebプラットフォームから簡単に実行できるはずです;)

Excelワークブック内に複数のワークシートまたは名前付きワークシートが必要な場合は、と呼ばれるXMLスキーマを介して同様のことができますSpreadSheetML。これはOffice 2007に付属する新しい形式ではなく、Excel 2000までさかのぼってまったく異なるものです。どのように機能するかを説明する最も簡単な方法は、例を使用することです。

<?xml version="1.0"?>
<?mso-application progid="Excel.Sheet"?> 
<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">
<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
      <Author>Your_name_here</Author>
      <LastAuthor>Your_name_here</LastAuthor>
      <Created>20080625</Created>
      <Company>ABC Inc</Company>
      <Version>10.2625</Version>
</DocumentProperties>
<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
        <WindowHeight>6135</WindowHeight>
        <WindowWidth>8445</WindowWidth>
        <WindowTopX>240</WindowTopX>
        <WindowTopY>120</WindowTopY>
        <ProtectStructure>False</ProtectStructure>
        <ProtectWindows>False</ProtectWindows>
</ExcelWorkbook>

<Styles>
      <Style ss:ID="Default" ss:Name="Normal">
            <Alignment ss:Vertical="Bottom" />
            <Borders />
            <Font />
            <Interior />
            <NumberFormat />
            <Protection />
      </Style>
</Styles>

<Worksheet ss:Name="Sample Sheet 1">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table1">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="Number">1</Data></Cell>
      <Cell><Data ss:Type="Number">2</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">3</Data></Cell>
      <Cell><Data ss:Type="Number">4</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">5</Data></Cell>
      <Cell><Data ss:Type="Number">6</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="Number">7</Data></Cell>
      <Cell><Data ss:Type="Number">8</Data></Cell>
</Row>
</Table>
</Worksheet>

<Worksheet ss:Name="Sample Sheet 2">
<Table ss:ExpandedColumnCount="2" x:FullColumns="1" x:FullRows="1" ID="Table2">
<Column ss:Width="150" />
<Column ss:Width="200" />
<Row>
      <Cell><Data ss:Type="String">A</Data></Cell>
      <Cell><Data ss:Type="String">B</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">C</Data></Cell>
      <Cell><Data ss:Type="String">D</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">E</Data></Cell>
      <Cell><Data ss:Type="String">F</Data></Cell>
</Row>
<Row>
      <Cell><Data ss:Type="String">G</Data></Cell>
      <Cell><Data ss:Type="String">H</Data></Cell>
</Row>
</Table>
</Worksheet>
</Workbook> 

12
ファイルの名前を.xml extensioに変更して次のように追加できます。<?mso-application progid = "Excel.Sheet"?>の直後に<?xml version = "1.0"?>このようにして、ウィンドウはファイルがExcelファイルは、適切なアイコンを提供し、ファイルをクリックするとExcelを開きます。Excelは、ファイル形式と内容が一致しないことを警告しません。さようなら。
pomarc 2009年

1
@pomarcその欠点は、Excelファイルをインポートする他のプログラムがそれを認識しないことです。しかし、そうすると、おそらくxmlを解析できなくなります。
Joel Coehoorn、2010年

1
私はこのテクニックをかなりうまく使いました。これは私のお勧めです-シンプルで非常に効果的な汚れ。
NealB

XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。
iokevins '30

わかりやすくするために、HTMLテーブルについては触れましたが、この答えの主なポイントはSpreadsheetMLであり、これは単なるHTML表形式データではありません。Excelはそれをネイティブと見なします。
Joel Coehoorn 2013年

16

DataTableからの場合:

public static void DataTabletoXLS(DataTable DT, string fileName)
{
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-16";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    string tab = "";
    foreach (DataColumn dc in DT.Columns)
    {
        HttpContext.Current.Response.Write(tab + dc.ColumnName.Replace("\n", "").Replace("\t", ""));
        tab = "\t";
    }
    HttpContext.Current.Response.Write("\n");

    int i;
    foreach (DataRow dr in DT.Rows)
    {
        tab = "";
        for (i = 0; i < DT.Columns.Count; i++)
        {
            HttpContext.Current.Response.Write(tab + dr[i].ToString().Replace("\n", "").Replace("\t", ""));
            tab = "\t";
        }
        HttpContext.Current.Response.Write("\n");
    }
    HttpContext.Current.Response.End();
}

グリッドビューから:

public static void GridviewtoXLS(GridView gv, string fileName)
{
    int DirtyBit = 0;
    int PageSize = 0;
    if (gv.AllowPaging == true)
    {
        DirtyBit = 1;
        PageSize = gv.PageSize;
        gv.AllowPaging = false;
        gv.DataBind();
    }

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Charset = "utf-8";
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    HttpContext.Current.Response.AddHeader(
        "content-disposition", string.Format("attachment; filename={0}.xls", fileName));
    HttpContext.Current.Response.ContentType = "application/ms-excel";

    using (StringWriter sw = new StringWriter())
    using (HtmlTextWriter htw = new HtmlTextWriter(sw))
    {
        //  Create a table to contain the grid
        Table table = new Table();

        //  include the gridline settings
        table.GridLines = gv.GridLines;

        //  add the header row to the table
        if (gv.HeaderRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.HeaderRow);
            table.Rows.Add(gv.HeaderRow);
        }

        //  add each of the data rows to the table
        foreach (GridViewRow row in gv.Rows)
        {
            Utilities.Export.PrepareControlForExport(row);
            table.Rows.Add(row);
        }

        //  add the footer row to the table
        if (gv.FooterRow != null)
        {
            Utilities.Export.PrepareControlForExport(gv.FooterRow);
            table.Rows.Add(gv.FooterRow);
        }

        //  render the table into the htmlwriter
        table.RenderControl(htw);

        //  render the htmlwriter into the response
        HttpContext.Current.Response.Write(sw.ToString().Replace("£", ""));
        HttpContext.Current.Response.End();
    }

    if (DirtyBit == 1)
    {
        gv.PageSize = PageSize;
        gv.AllowPaging = true;
        gv.DataBind();
    }
}

private static void PrepareControlForExport(Control control)
{
    for (int i = 0; i < control.Controls.Count; i++)
    {
        Control current = control.Controls[i];
        if (current is LinkButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as LinkButton).Text));
        }
        else if (current is ImageButton)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as ImageButton).AlternateText));
        }
        else if (current is HyperLink)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as HyperLink).Text));
        }
        else if (current is DropDownList)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as DropDownList).SelectedItem.Text));
        }
        else if (current is CheckBox)
        {
            control.Controls.Remove(current);
            control.Controls.AddAt(i, new LiteralControl((current as CheckBox).Checked ? "True" : "False"));
        }

        if (current.HasControls())
        {
            Utilities.Export.PrepareControlForExport(current);
        }
    }
}

1
必要なコードだけに感謝します。:)
Kjensen

スコット、ポンド( "£")記号は何ですか?必要な場合はどうなりますか?危険な他のキャラクターは?
Piotr Owsiak

完璧です。ちょうど私が必要としたもの。
Brad Bruce

£記号は、実際に私が私の顧客の1人に必要なものにすぎません。取り出せます。
SpoiledTechie.com 2010

XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。CSVデータファイルも、Microsoft Excelで開いたときに1位になります。
iokevins '30


5

与えられた回答と同僚との協議に基づくと、最良の解決策は、XMLファイルまたはHTMLテーブルを生成し、それを添付ファイルとしてプッシュすることです。私の同僚が推奨する1つの変更は、データ(つまりHTMLテーブル)を直接Responseオブジェクトに書き込むことができるため、ファイルを書き出す必要がなくなることです。これは、権限の問題やI / Oが原因で面倒な場合があります。競合、およびスケジュールされたパージが発生することを確認します。

これがコードのスニペットです...私はこれをまだチェックしていませんし、呼び出されたコードのすべてを提供していませんが、それはアイデアをよく表していると思います。

    Dim uiTable As HtmlTable = GetUiTable(groupedSumData)

    Response.Clear()

    Response.ContentType = "application/vnd.ms-excel"
    Response.AddHeader("Content-Disposition", String.Format("inline; filename=OSSummery{0:ddmmssf}.xls", DateTime.Now))

    Dim writer As New System.IO.StringWriter()
    Dim htmlWriter As New HtmlTextWriter(writer)
    uiTable.RenderControl(htmlWriter)
    Response.Write(writer.ToString)

    Response.End()

2
ダン、あなたは正しい軌道に乗っています。そして、HTMLのサポートがイライラして制限されているため、SpreadsheetML over HTMLをお勧めします。ただし、HTML、SpreadsheetML、およびOpenXMLでは、ファイルサイズがかなり大きくなり、サーバーによってgzip圧縮されません。OpenXMLに複数のファイルを含むZIPコンテナーが必要です。SpreadsheetMLとHTMLは、最初にそれらを圧縮し、そのzipを添付ファイルとして送信すると、ダウンロードがはるかに高速になります。SharpZipLibを使用して、Responseに直接ストリーミングするのではなく、それにストリーミングします。
richardtallent 2009

4

ExcelはHTMLを理解するので、.xls拡張子の付いた一時ファイルにHTMLテーブルとしてデータを書き込み、ファイルのFileInfoを取得し、次を使用してそれをブローバックできます。

Response.Clear();
Response.AddHeader("Content-Disposition", "attachment; filename=" + fi.Name);
Response.AddHeader("Content-Length", fi.Length.ToString());
Response.ContentType = "application/octet-stream";
Response.WriteFile(fi.FullName);
Response.End();

一時ファイルを避けたい場合は、WriteFileを使用する代わりに、メモリ内ストリームに書き込み、バイトを書き戻すことができます。

content-lengthヘッダーが省略されている場合は、直接htmlを書き込むことができますが、これはすべてのブラウザーで常に正しく機能しない可能性があります


2
XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。
iokevins '30 / 07/30

3

個人的にはXML方式を好みます。データベースからのデータをデータセットで返し、それをXMlに保存します。次に、適切なドキュメントをフォーマットする変換ルールを含むxsltファイルを作成し、単純なXML変換でジョブを完了します。セルの書式設定、条件付き書式設定、ヘッダーとフッターの設定、さらには印刷範囲の設定を行うことができます。


2

私はこれを数回行いましたが、最も簡単な方法は、CSV(カンマ区切り値)ファイルを返すことでした。Excelはそれを完全にインポートし、比較的高速です。


CSVデータに関する1つの潜在的な問題(YMMV):Microsoft Excelは、先行スペースとゼロを自動的にトリムします
iokevins '30 / 07/30

2

常に優れたデータグリッドからデータをエクスポートします。HTMLに変換してからExcelファイルに書き込む

Response.ContentType = "application/vnd.ms-excel"
    Response.Charset = ""
    Response.AddHeader("content-disposition", "fileattachment;filename=YOURFILENAME.xls")
    Me.EnableViewState = False
    Dim sw As System.IO.StringWriter = New System.IO.StringWriter
    Dim hw As HtmlTextWriter = New HtmlTextWriter(sw)
    ClearControls(grid)
    grid.RenderControl(hw)
    Response.Write(sw.ToString())
    Response.End()

このメソッドの唯一の問題は、多くのグリッドにボタンまたはリンクが含まれているため、これも必要です。

'needed to export grid to excel to remove link button control and represent as text
Private Sub ClearControls(ByVal control As Control)
    Dim i As Integer
    For i = control.Controls.Count - 1 To 0 Step -1
        ClearControls(control.Controls(i))
    Next i

    If TypeOf control Is System.Web.UI.WebControls.Image Then
        control.Parent.Controls.Remove(control)
    End If

    If (Not TypeOf control Is TableCell) Then
        If Not (control.GetType().GetProperty("SelectedItem") Is Nothing) Then
            Dim literal As New LiteralControl
            control.Parent.Controls.Add(literal)
            Try
                literal.Text = CStr(control.GetType().GetProperty("SelectedItem").GetValue(control, Nothing))
            Catch
            End Try
            control.Parent.Controls.Remove(control)
        Else
            If Not (control.GetType().GetProperty("Text") Is Nothing) Then
                Dim literal As New LiteralControl
                control.Parent.Controls.Add(literal)
                literal.Text = CStr(control.GetType().GetProperty("Text").GetValue(control, Nothing))
                control.Parent.Controls.Remove(control)
            End If
        End If
    End If
    Return
End Sub

どこかでうまくいくことがわかりました。


2
XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。
iokevins、2011


2

これは、ストアドプロシージャから取得したレポートです。結果はExcelにエクスポートされます。ADO.NETの代わりにADOを使用している理由と、この行の理由

oSheet.Cells(2, 1).copyfromrecordset(rst1)

ほとんどの作業を行い、ado.netでは利用できません。

‘Calls stored proc in SQL Server 2000 and puts data in Excel and ‘formats it

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim cnn As ADODB.Connection
        cnn = New ADODB.Connection
        cnn.Open("Provider=SQLOLEDB;data source=xxxxxxx;" & _
          "database=xxxxxxxx;Trusted_Connection=yes;")

        Dim cmd As New ADODB.Command


        cmd.ActiveConnection = cnn


        cmd.CommandText = "[sp_TomTepley]"
        cmd.CommandType = ADODB.CommandTypeEnum.adCmdStoredProc
        cmd.CommandTimeout = 0
        cmd.Parameters.Refresh()


        Dim rst1 As ADODB.Recordset
        rst1 = New ADODB.Recordset
        rst1.Open(cmd)

        Dim oXL As New Excel.Application
        Dim oWB As Excel.Workbook
        Dim oSheet As Excel.Worksheet

        'oXL = CreateObject("excel.application")
        oXL.Visible = True
        oWB = oXL.Workbooks.Add
        oSheet = oWB.ActiveSheet

        Dim Column As Integer
        Column = 1

        Dim fld As ADODB.Field
        For Each fld In rst1.Fields

            oXL.Workbooks(1).Worksheets(1).Cells(1, Column).Value = fld.Name
            oXL.Workbooks(1).Worksheets(1).cells(1, Column).Interior.ColorIndex = 15
            Column = Column + 1

        Next fld

        oXL.Workbooks(1).Worksheets(1).name = "Tom Tepley Report"
        oSheet.Cells(2, 1).copyfromrecordset(rst1)
        oXL.Workbooks(1).Worksheets(1).Cells.EntireColumn.AutoFit()


        oXL.Visible = True
        oXL.UserControl = True

        rst1 = Nothing

        cnn.Close()
        Beep()

    End Sub

1

GridViewにデータを入力する場合、この関数を使用してHTML形式のデータを取得できますが、ブラウザーにそれがExcelファイルであることを示します。

 Public Sub ExportToExcel(ByVal fileName As String, ByVal gv As GridView)

        HttpContext.Current.Response.Clear()
        HttpContext.Current.Response.AddHeader("content-disposition", String.Format("attachment; filename={0}", fileName))
        HttpContext.Current.Response.ContentType = "application/ms-excel"

        Dim sw As StringWriter = New StringWriter
        Dim htw As HtmlTextWriter = New HtmlTextWriter(sw)
        Dim table As Table = New Table

        table.GridLines = gv.GridLines

        If (Not (gv.HeaderRow) Is Nothing) Then
            PrepareControlForExport(gv.HeaderRow)
            table.Rows.Add(gv.HeaderRow)
        End If

        For Each row As GridViewRow In gv.Rows
            PrepareControlForExport(row)
            table.Rows.Add(row)
        Next

        If (Not (gv.FooterRow) Is Nothing) Then
            PrepareControlForExport(gv.FooterRow)
            table.Rows.Add(gv.FooterRow)
        End If

        table.RenderControl(htw)

        HttpContext.Current.Response.Write(sw.ToString)
        HttpContext.Current.Response.End()

    End Sub


    Private Sub PrepareControlForExport(ByVal control As Control)

        Dim i As Integer = 0

        Do While (i < control.Controls.Count)

            Dim current As Control = control.Controls(i)

            If (TypeOf current Is LinkButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, LinkButton).Text))

            ElseIf (TypeOf current Is ImageButton) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, ImageButton).AlternateText))

            ElseIf (TypeOf current Is HyperLink) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, HyperLink).Text))

            ElseIf (TypeOf current Is DropDownList) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, DropDownList).SelectedItem.Text))

            ElseIf (TypeOf current Is CheckBox) Then
                control.Controls.Remove(current)
                control.Controls.AddAt(i, New LiteralControl(CType(current, CheckBox).Checked))

            End If

            If current.HasControls Then
                PrepareControlForExport(current)
            End If

            i = i + 1

        Loop

    End Sub

XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。
iokevins '30

1

Microsoft.Office.Interop名前空間を介したCOM相互運用を避けてください。それはとても遅いので、信頼性が低く、スケーラブルではありません。マゾには適用されません。



0

CSVが最も簡単な方法です。ほとんどの場合、Excelにリンクされています。それ以外の場合は、オートメーションAPIまたはXML形式を使用する必要があります。APIとXMLはそれほど使いにくいものではありません。

Excel用のXMLの生成に関する情報


0

私は(上記のように)CSVルートを使用するか、または最近ではInfragistics NetAdvantageを使用してファイルを生成しています。(Infragisticsが関係しているほとんどの時間、既存のUltraWebGridをエクスポートしています。これは、追加のフォーマット調整が必要でない限り、本質的に1 LOCソリューションです。Excel/ BIFFファイルを手動で生成することもできます。ただし、必要になることはめったにありません。)


0

男、.netではそれを実行できるコンポーネントがあると思いますが、クラシックASPではすでにHTMLテーブルを作成し、ページのMIMEティップをvnd / msexcelに変更しています。gridviewはhtmlテーブルであるため、gridviewを使用してMIMEタイプを変更した場合、おそらく機能するはずです。


XLSファイルとしてマスクされたHTML表形式データの2つの潜在的な問題(YMMV):(1)Microsoft Excelは、先行スペースとゼロを自動的にトリムします。(2)Microsoft Excel 2010は、HTML表形式データを含むXLSファイルを開くときにユーザーに警告します。#1の解決策は、creativyst.com / Doc / Articles / CSV / CSV01.htm#CSVAndExcelです(先行スペース/ゼロが重要であり、保持する必要がある場合)。
iokevins 2011

0

「これらの数値はテキストとして格納されているように見える」緑色の三角形を回避する唯一の防弾方法は、Open XML形式を使用することです。避けられない緑色の三角形を避けるために、それを使用する価値があります。


0

Excelレポートで見た最善の方法は、XML拡張機能を使用してXMLでデータを書き出し、正しいコンテンツタイプでクライアントにストリーミングすることです。(アプリケーション/ xls)

これは、基本的なフォーマットが必要なすべてのレポートで機能し、テキスト比較ツールを使用して既存のスプレッドシートと比較できます。


0

これがイントラネット用であり、アクセス許可を設定してIEを要求できる場合、Excelを駆動するJScript / VBScriptを使用してワークブッククライアント側を生成できます。これにより、サーバー上でExcelを自動化する手間をかけずに、ネイティブのExcel書式を設定できます。

かなりニッチなシナリオを除いて、私がこのアプローチを本当にお勧めするかどうかはわかりませんが、古典的なASPの全盛期にはかなり一般的でした。


0

もちろん、いつでもサードパーティのコンポーネントを使用できます。個人的に、私はSpire.XLS http://www.e-iceblue.com/xls/xlsintro.htmで良い経験をしました

コンポーネントはアプリケーション内で非常に使いやすくなっています。

        Workbook workbook = new Workbook();

        //Load workbook from disk.
        workbook.LoadFromFile(@"Data\EditSheetSample.xls");
        //Initailize worksheet
        Worksheet sheet = workbook.Worksheets[0];

        //Writes string
        sheet.Range["B1"].Text = "Hello,World!";
        //Writes number
        sheet.Range["B2"].NumberValue = 1234.5678;
        //Writes date
        sheet.Range["B3"].DateTimeValue = System.DateTime.Now;
        //Writes formula
        sheet.Range["B4"].Formula = "=1111*11111";

        workbook.SaveToFile("Sample.xls");

0

上記で提案された解決策の1つを使用して私が遭遇した問題の1つは、この回答に似ていますが、コンテンツを添付ファイルとしてプッシュすると(非msブラウザーの最もクリーンな解決策であることがわかりました) 、それをExcel 2000-2003で開きます。そのタイプは「Excel Webページ」であり、ネイティブExcelドキュメントではありません。

次に、Excel内から「ファイルの種類」を使用してExcelドキュメントに変換する方法をユーザーに説明する必要があります。これは、ユーザーがこのドキュメントを編集してから、サイトに再度アップロードする必要がある場合の問題です。

私の推奨はCSVを使用することです。これは簡単で、ユーザーがExcel内から開く場合、Excelは少なくともネイティブ形式で保存するように求めます。


ユーザーが世界中に散在している場合は、CSVに注意する必要があります。ここドイツでは、コンマが小数点として使用されているため、セミコロンが値の区切りとして使用されます。すべての異なる文化で読み取り可能な1つのファイルを作成することが困難になります。したがって、私の投票はXML形式の1つです。
ポール

0

私はデータに基づいてCSVファイルを作成するだけです。それは、それが最もクリーンであり、Excelがそれを十分にサポートしているからです。しかし、より柔軟なフォーマットが必要な場合は、実際のExcelファイルを生成するためのサードパーティツールがいくつかあるはずです。


0

以下は、データテーブルをCSVとしてストリーミングするソリューションです。高速、クリーン、そして簡単で、入力のコンマを処理します。

public static void ExportToExcel(DataTable data, HttpResponse response, string fileName)
{
    response.Charset = "utf-8";
    response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
    response.Cache.SetCacheability(HttpCacheability.NoCache);
    response.ContentType = "text/csv";
    response.AddHeader("Content-Disposition", "attachment; filename=" + fileName);

    for (int i = 0; i < data.Columns.Count; i++)
    {
       response.Write(data.Columns[i].ColumnName);
       response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
    }        
    foreach (DataRow row in data.Rows)
    {
        for (int i = 0; i < data.Columns.Count; i++)
        {
            response.Write(String.Format("\"{0}\"", row[i].ToString()));
            response.Write(i == data.Columns.Count - 1 ? "\n" : ",");
        }
    }

    response.End();
}

-1

Webフォームからエクスポートする関数を作成し、C#が他の人に役立つことを願ってC#を作成しました

    public void ExportFileFromSPData(string filename, DataTable dt)
    {
        HttpResponse response = HttpContext.Current.Response;

        //clean up the response.object
        response.Clear();
        response.Buffer = true;
        response.Charset = "";

        // set the response mime type for html so you can see what are you printing 
        //response.ContentType = "text/html";
        //response.AddHeader("Content-Disposition", "attachment;filename=test.html");

        // set the response mime type for excel
        response.ContentType = "application/vnd.ms-excel";
        response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
        response.ContentEncoding = System.Text.Encoding.UTF8;
        response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble());

        //style to format numbers to string
        string style = @"<style> .text { mso-number-format:\@; } </style>";
        response.Write(style);

        // create a string writer
        using (StringWriter sw = new StringWriter())
        {
            using (HtmlTextWriter htw = new HtmlTextWriter(sw))
            {
                // instantiate a datagrid
                GridView dg = new GridView();
                dg.DataSource = dt;
                dg.DataBind();

                foreach (GridViewRow datarow in dg.Rows)
                {
                    //format specific cell to be text 
                    //to avoid 1.232323+E29 to get 1232312312312312124124
                    datarow.Cells[0].Attributes.Add("class", "text");
                }

                dg.RenderControl(htw);
                response.Write(sw.ToString());
                response.End();
            }
        }
     }

-5

CSVファイルの代わりにExcelを使用する必要がある場合は、サーバーの1つのExcelインスタンスでOLEオートメーションを使用する必要があります。これを行う最も簡単な方法は、テンプレートファイルを用意し、プログラムでデータを入力することです。別のファイルに保存します。

チップ:

  • インタラクティブに行わないでください。ユーザーにプロセスを開始してから、ファイルへのリンクを含むページを投稿してもらいます。これにより、スプレッドシートの生成中の潜在的なパフォーマンスの問題が軽減されます。
  • 前述のテンプレートを使用します。変更が簡単になります。
  • Excelがダイアログをポップアップしないように設定されていることを確認してください。Webサーバーでは、これによりExcelインスタンス全体がハングします。
  • 潜在的なセキュリティホールとして公開されないように、できればファイアウォールの内側にある別のサーバーにExcelインスタンスを保持します。
  • リソースの使用状況に注意してください。OLEオートメーションインターフェイスを介してスプレッドシートを生成する(PIAはこれの単なるシムです)のは、かなり重いプロセスです。これを大量のデータにスケーリングする必要がある場合は、アーキテクチャをある程度賢くする必要があるかもしれません。

「MIMEタイプを使用してExcelをだましてHTMLテーブルを開く」アプローチの一部は、ファイルの形式が少し基本的であることを気にしない場合に機能します。これらのアプローチは、CPUの負荷が重い作業をクライアントに移します。スプレッドシートのフォーマットを細かく制御したい場合は、上記のようにExcel自体を使用してファイルを生成する必要があります。


Webサーバーから自動化を行うのは悪い考えです。代替案はハックっぽく見えるかもしれませんが、実際にははるかにうまく機能します。
Joel Coehoorn、2008

私たちはExcelでサーバー側のOLEを使用しており、それは裏側で非常に苦痛です。製品へのリスクがなければ**、別のソリューションを使用します。**あなたが知っている悪魔の方がいい...
DaveE 2010
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.