回答:
長所:
短所:
長所:
短所:
長所:
短所:
長所:
短所:
長所:
短所:
長所:
短所:
データを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>
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);
}
}
}
与えられた回答と同僚との協議に基づくと、最良の解決策は、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()
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を書き込むことができますが、これはすべてのブラウザーで常に正しく機能しない可能性があります
私はこれを数回行いましたが、最も簡単な方法は、CSV(カンマ区切り値)ファイルを返すことでした。Excelはそれを完全にインポートし、比較的高速です。
常に優れたデータグリッドからデータをエクスポートします。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
どこかでうまくいくことがわかりました。
OpenXMLに基づく無料のオープンソースのExcel生成ライブラリをお勧めします
それは数ヶ月前に私を助けました。
これは、ストアドプロシージャから取得したレポートです。結果は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
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
このライブラリを使用すると、非常に簡単に、うまくフォーマットされたExcelファイルを作成できます:http : //officehelper.codeplex.com/documentation。
Microsoft OfficeをWebサーバーにインストールする必要はありません。
CSVが最も簡単な方法です。ほとんどの場合、Excelにリンクされています。それ以外の場合は、オートメーションAPIまたはXML形式を使用する必要があります。APIとXMLはそれほど使いにくいものではありません。
男、.netではそれを実行できるコンポーネントがあると思いますが、クラシックASPではすでにHTMLテーブルを作成し、ページのMIMEティップをvnd / msexcelに変更しています。gridviewはhtmlテーブルであるため、gridviewを使用してMIMEタイプを変更した場合、おそらく機能するはずです。
これがイントラネット用であり、アクセス許可を設定してIEを要求できる場合、Excelを駆動するJScript / VBScriptを使用してワークブッククライアント側を生成できます。これにより、サーバー上でExcelを自動化する手間をかけずに、ネイティブのExcel書式を設定できます。
かなりニッチなシナリオを除いて、私がこのアプローチを本当にお勧めするかどうかはわかりませんが、古典的なASPの全盛期にはかなり一般的でした。
もちろん、いつでもサードパーティのコンポーネントを使用できます。個人的に、私は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");
上記で提案された解決策の1つを使用して私が遭遇した問題の1つは、この回答に似ていますが、コンテンツを添付ファイルとしてプッシュすると(非msブラウザーの最もクリーンな解決策であることがわかりました) 、それをExcel 2000-2003で開きます。そのタイプは「Excel Webページ」であり、ネイティブExcelドキュメントではありません。
次に、Excel内から「ファイルの種類」を使用してExcelドキュメントに変換する方法をユーザーに説明する必要があります。これは、ユーザーがこのドキュメントを編集してから、サイトに再度アップロードする必要がある場合の問題です。
私の推奨はCSVを使用することです。これは簡単で、ユーザーがExcel内から開く場合、Excelは少なくともネイティブ形式で保存するように求めます。
以下は、データテーブルを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();
}
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();
}
}
}
CSVファイルの代わりにExcelを使用する必要がある場合は、サーバーの1つのExcelインスタンスでOLEオートメーションを使用する必要があります。これを行う最も簡単な方法は、テンプレートファイルを用意し、プログラムでデータを入力することです。別のファイルに保存します。
チップ:
「MIMEタイプを使用してExcelをだましてHTMLテーブルを開く」アプローチの一部は、ファイルの形式が少し基本的であることを気にしない場合に機能します。これらのアプローチは、CPUの負荷が重い作業をクライアントに移します。スプレッドシートのフォーマットを細かく制御したい場合は、上記のようにExcel自体を使用してファイルを生成する必要があります。