Gerando um arquivo do Excel no ASP.NET [fechado]
-
02-07-2019 - |
Pergunta
Estou prestes a adicionar uma seção para um aplicativo ASP.NET (VB.NET codebehind) que permitirá que um usuário para obter dados retornados a eles como um arquivo do Excel, que vai gerar com base em dados de banco de dados. Embora existam várias maneiras de fazer isso, cada um tem suas próprias desvantagens. Como seria você retornar os dados? Eu estou procurando algo que é tão limpo e simples quanto possível.
Solução
CSV
Pros:
- Simples
Contras:
- Pode não funcionar em outros locais ou em diferentes configurações do Excel (ou seja, separador de lista)
- Não é possível aplicar a formatação, fórmulas, etc
HTML
Pros:
- Ainda bem simples
- Suporta formatação simples e fórmulas
Contras:
- Você tem que nomear o arquivo como xls e Excel pode avisá-lo sobre a abertura de um arquivo Excel não nativa
- Uma planilha por pasta de trabalho
OpenXML (Office 2007 .xlsx)
Pros:
- formato nativo Excel
- Suporta todos os Excel apresenta ??li>
- Não requerem uma cópia de instalação do Excel
- É possível gerar tabelas dinâmicas
- Pode ser gerado usando projeto de código aberto EPPlus
Contras:
- compatibilidade limitada fora Excel 2007 (não deve ser um problema hoje em dia)
- Complicated menos que você esteja usando um componente de terceiros
SpreadsheetML (formato XML aberto)
Pros:
- simples em comparação com formatos nativos do Excel
- suporta a maioria dos recursos do Excel: formatação, estilos, fórmulas, várias folhas por livro
- Excel não precisa ser instalado para usá-lo
- Não há bibliotecas de terceiros necessário - basta escrever o seu xml
- Os documentos podem ser abertos pelo Excel XP / 2003/2007
Contras:
- A falta de uma boa documentação
- Não suportado em versões mais antigas do Excel (pré-2000)
- Write-only, em que uma vez que você abri-lo e fazer alterações de Excel é convertido em Excel nativa.
XLS (gerado pelo componente de terceiros)
Pros:
- Gerar arquivo nativo Excel com toda a formatação, fórmulas, etc.
Contras:
- dinheiro Custo
- Adicionar dependências
COM Interop
Pros:
- Usa bibliotecas nativas da Microsoft
- Suporte de leitura para documentos nativos
Contras:
- Muito lento questões
- Dependência / versão de harmonização
- Concorrência / problemas de integridade de dados para uso da web quando leitura
- Muito lento
- Escala questões para o uso da web (diferente da concorrência): necessidade de criar várias instâncias de aplicativo pesado Excel no servidor
- Requer o Windows
- Eu mencionei que ele é lento?
Outras dicas
Você pode enviar os dados como células de tabela HTML, furar um .xls
ou extensão .xlsx
sobre ele, e Excel irá abri-lo como se fosse um documento nativa. Você pode até mesmo fazer alguns cálculos de formatação limitadas e fórmula dessa maneira, por isso é muito mais poderoso do CSV. Além disso, a saída de uma tabela html deve ser muito fácil de fazer a partir de uma plataforma web como ASP.Net;)
Se você precisar de várias planilhas ou planilhas nomeados dentro de sua pasta de trabalho Excel, você pode fazer algo semelhante através de um esquema XML chamado SpreadSheetML
. Esta é não o novo formato que acompanha o Office 2007, mas algo completamente diferente que as obras já em Excel 2000. A maneira mais fácil de explicar como ele funciona é com um exemplo:
<?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>
Se vindo de um 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();
}
A partir de um Gridview :
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);
}
}
}
Este é um wrapper livre em torno SpreadML - ele funciona muito bem.
Com base nas respostas dadas, e consultas com colegas de trabalho, parece que a melhor solução é gerar tanto um arquivo XML ou tabelas HTML e empurrá-lo para baixo como um anexo. A única mudança recomendado pelos meus colegas de trabalho é que os dados (ou seja, as tabelas HTML) pode ser escrito diretamente ao objeto Response, eliminando assim a necessidade de escrever um arquivo, que pode ser problemático devido a problemas de permissões, I / O contenção, e garantindo que purga programado ocorre.
Aqui está um trecho do código ... Eu não tenho verificado isso ainda, e eu não ter fornecido todo o código chamado, mas eu acho que ela representa bem a idéia.
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()
desde Excel entende HTML você pode apenas escrever os dados como uma tabela HTML para um arquivo temporário com uma extensão .xls, obter o FileInfo para o arquivo, e explodi-lo de volta usando
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();
Se você queria evitar o arquivo temporário, você pode escrever para um fluxo na memória e escrever os bytes de volta em vez de usar WriteFile
Se o cabeçalho Content-Length é omitido você poderia simplesmente escrever o html volta diretamente, mas isso pode não funcionar corretamente o tempo todo em todos os navegadores
Eu pessoalmente prefiro o método XML. Vou retornar os dados do banco de dados em um conjunto de dados, salve-o em XML, então eu criar um arquivo XSLT que contém uma regra de transformação que irá formatar um documento apropriado, e um XML simples transformar vai terminar o trabalho para cima. A melhor parte sobre isso, você pode formatar células, fazer a formatação condicional, cabeçalhos e rodapés de instalação, e até mesmo definir intervalos de impressão.
Já fiz isso algumas vezes e cada vez que a maneira mais fácil era simplesmente retornar um CSV (Comma Separated Value) de arquivos. importações do Excel-lo perfeitamente, e é relativamente rápido de fazer.
podemos exportar dados de um datagrid para excel o tempo todo. Convertê-lo para HTML, em seguida, escrever para um arquivo 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()
A única pegadinha com este método é que um monte de nossas redes tinha botões ou links neles assim que você precisa disso também:
'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
Eu descobri que em algum lugar, ele funciona bem.
Eu recomendo livre opensource geração excel libruary que é baseado no OpenXML
Ele me ajudou há vários meses.
Aqui está um relatório que puxa a partir de um procedimento armazenado. Os resultados são exportados para o Excel. Ele usa ADO em vez de ADO.NET e a razão por que é esta linha
oSheet.Cells(2, 1).copyfromrecordset(rst1)
Ele faz a maioria do trabalho e não está disponível em 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
Se você preencher um GridView com dados que você pode usar essa função para obter os dados formatadas em HTML, mas indicando o navegador é um arquivo 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
Apenas evitar interoperabilidade via Microsoft.Office.Interop namespace. É tão maldito lento e pouco confiável e unscalable. Não se aplica para masoquistas.
Você pode criar bem os arquivos do Excel usando esta biblioteca, muito facilmente formatado: http://officehelper.codeplex.com/ documentação .
Microsoft Office não precisa ser instalado no servidor web!
CSV é maneira mais fácil. Na maioria das vezes ela está ligada ao Excel. Caso contrário, você tem que usar as APIs de automação ou formato XML. As APIs e XML não que são difíceis de usar.
I quer ir a rota CSV (como descrito acima), ou mais frequentemente estes dias, eu uso Infragistics NetAdvantage para gerar o arquivo. (O próprio grande maioria das vezes, onde Infragistics está em jogo, nós estamos apenas exportar um UltraWebGrid existente, que é essencialmente uma solução one-LOC, a menos que são necessários ajustes de formatação extra. Poderíamos gerar manualmente um arquivo do Excel / BIFF, bem como, mas raramente há uma necessidade.)
homem, em .net eu acho que você poderia ter um componente que poderia fazer isso, mas em asp clássico que eu já ter feito isso criando uma tabela html e mudando o tipe mime da página para vnd / msexcel. Eu acho que se você usar um gridview e alterar o tipo de mime talvez ele deve funcionar, porque o gridview é uma tabela HTML.
A única maneira à prova de balas de evitar o "Parece que esses números são armazenados como texto" triângulos verdes é usar o formato Open XML. Vale a pena usá-lo, apenas para evitar os triângulos verdes inevitáveis.
O melhor método que eu vi para relatórios Excel está a escrever os dados em XML com uma extensão XML e transmiti-lo aos clientes com o tipo de conteúdo correto. (Application / xls)
Isso funciona para qualquer relatório que requer formatação básica, e permite-lhe comparar com planilhas existentes usando ferramentas de comparação de texto.
Assumindo que este é para uma intranet, onde você pode definir permissões e mandato IE, você pode gerar lado do cliente pasta de trabalho com JScript / VBScript condução Excel . Isto dá-lhe a formatação nativa Excel, sem o incômodo de tentar automatizar Excel no servidor.
Eu não tenho certeza eu realmente recomendo esta abordagem mais, exceto em bastante cenários de nicho, mas era bastante comum durante os tempos áureos ASP clássicas.
Pode, claro, sempre ir para uma componentes de terceiros. Pessoalmente, tenho tido uma boa experiência com Spire.XLS http: //www.e- iceblue.com/xls/xlsintro.htm
O componente é muito fácil de usar dentro de sua aplicação:
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");
Um dos problemas Corri tenho todo usando uma das soluções sugeridas acima, que são semelhantes a esta resposta é que se você empurrar o conteúdo como um anexo (o que eu encontrei para ser a solução mais limpa para os não-ms navegadores), em seguida, abri-lo no Excel 2000-2003, seu tipo é uma "página da web Excel" e não um documento nativo Excel.
Então você tem que explicar aos usuários como usar "Salvar como tipo" de dentro Excel para convertê-lo para um documento Excel. Esta é uma dor, se os usuários precisam editar este documento e, em seguida, re-enviá-lo para o seu site.
A minha recomendação é usar CSV. É simples e se os usuários fazem abri-lo a partir de dentro do Excel, Excel, pelo menos, pede-lhes para salvá-lo em seu formato nativo.
Gostaria apenas de criar um arquivo CSV com base nos dados, porque eu vejo isso como a mais limpa e Excel tem um bom suporte para ele. Mas se você precisar de um formato mais flexível, eu tenho certeza que há algumas ferramentas de 3 para gerar excel verdadeira arquivos.
Aqui está uma solução a transmite o fora tabela de dados como um CSV. Rápido, limpo e fácil, e ele lida com vírgulas na entrada.
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();
}
acabou de criar uma função para exportação a partir de um formulário web C # para excel espero que ajude outros
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();
}
}
}
Se você tiver que usar o Excel em vez de um arquivo CSV que você vai precisar usar automação OLE em uma instância Excel um servidor. A maneira mais fácil de fazer isso é ter um arquivo de modelo e programaticamente preenchê-lo com os dados. Você salvá-lo em outro arquivo.
Dicas:
- Não faça isso de forma interativa. Tem o pontapé de usuário fora do processo e, em seguida, postar uma página com o link para o arquivo. Isso reduz possíveis problemas de desempenho enquanto a planilha é gerada.
- Use o modelo como eu descrevi antes. Ela torna mais fácil para modificá-lo.
- Certifique-se de que o Excel está definido para não aparecer diálogos. Em um servidor web esta irá travar toda a instância excel.
- Mantenha a instância do Excel em um servidor separado, de preferência atrás de um firewall, por isso não é exposto como uma potencial falha de segurança.
- Fique de olho no uso de recursos. Gerando um spreadhseet sobre a interface de automação OLE (os da PIA são calços pouco mais este) é um processo bastante pesado. Se você precisa de escala isso para grandes volumes de dados que você pode precisar de ser um pouco inteligente com sua arquitetura.
Alguns dos 'uso mime-types para enganar excel em uma tabela HTML de abertura' abordagens iria funcionar se você não se importa o formato do arquivo a ser um pouco básico. Essas abordagens também fob a pesada CPU trabalho off para o cliente. Se você quer controle graned-fino sobre o formato da planilha que você provavelmente terá que usar o próprio Excel para gerar o arquivo como descrito acima.