Como criar uma planilha do Excel com C # sem exigir a instalação do Excel na máquina que está executando o código?
Como criar uma planilha do Excel com C # sem exigir a instalação do Excel na máquina que está executando o código?
Respostas:
Você pode usar uma biblioteca chamada ExcelLibrary. É uma biblioteca gratuita e de código aberto publicada no Google Code:
Parece ser uma porta do PHP ExcelWriter que você mencionou acima. Ele ainda não gravará no novo formato .xlsx, mas eles estão trabalhando para adicionar essa funcionalidade no.
É muito simples, pequeno e fácil de usar. Além disso, possui um DataSetHelper que permite usar DataSets e DataTables para trabalhar facilmente com dados do Excel.
O ExcelLibrary parece ainda funcionar apenas para o formato antigo do Excel (arquivos .xls), mas pode estar adicionando suporte no futuro para os formatos mais recentes do 2007/2010.
Você também pode usar o EPPlus , que funciona apenas para arquivos no formato Excel 2007/2010 (arquivos .xlsx). Há também NPOI que funciona com ambos.
Existem alguns erros conhecidos em cada biblioteca, conforme observado nos comentários. Ao todo, o EPPlus parece ser a melhor escolha com o passar do tempo. Parece ser mais ativamente atualizado e documentado também.
Além disso, conforme observado por @ АртёмЦарионов abaixo, o EPPlus tem suporte para Tabelas Dinâmicas e o ExcelLibrary pode ter algum suporte ( problema de tabela dinâmica no ExcelLibrary )
Aqui estão alguns links para referência rápida:
ExcelLibrary - GNU Lesser GPL
EPPlus - GNU Lesser General Public License (LGPL)
NPOI - Licença Apache
Aqui estão alguns exemplos de código para o ExcelLibrary:
Aqui está um exemplo pegando dados de um banco de dados e criando uma pasta de trabalho a partir dele. Observe que o código ExcelLibrary é a única linha na parte inferior:
//Create the data set and table
DataSet ds = new DataSet("New_DataSet");
DataTable dt = new DataTable("New_DataTable");
//Set the locale for each
ds.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
dt.Locale = System.Threading.Thread.CurrentThread.CurrentCulture;
//Open a DB connection (in this example with OleDB)
OleDbConnection con = new OleDbConnection(dbConnectionString);
con.Open();
//Create a query and fill the data table with the data from the DB
string sql = "SELECT Whatever FROM MyDBTable;";
OleDbCommand cmd = new OleDbCommand(sql, con);
OleDbDataAdapter adptr = new OleDbDataAdapter();
adptr.SelectCommand = cmd;
adptr.Fill(dt);
con.Close();
//Add the table to the data set
ds.Tables.Add(dt);
//Here's the easy part. Create the Excel worksheet from the data set
ExcelLibrary.DataSetHelper.CreateWorkbook("MyExcelFile.xls", ds);
Criar o arquivo do Excel é tão fácil quanto isso. Você também pode criar manualmente arquivos do Excel, mas a funcionalidade acima é o que realmente me impressionou.
Se você está satisfeito com o formato xlsx, experimente meu projeto GitHub, EPPlus . Tudo começou com a fonte do ExcelPackage, mas hoje é uma reescrita total. Ele suporta intervalos, estilo de célula, gráficos, formas, imagens, intervalos nomeados, AutoFiltro e muitas outras coisas.
E quanto ao uso do Open XML SDK 2.0 para Microsoft Office?
Alguns benefícios:
Ligações:
Usei com sucesso os seguintes projetos de código aberto:
ExcelPackage para formatos OOXML (Office 2007)
NPOI para o formato .XLS (Office 2003). O NPOI 2.0 (Beta) também suporta XLSX.
Dê uma olhada nas minhas postagens no blog:
Você pode usar o OLEDB para criar e manipular arquivos do Excel. Verifique isto: Lendo e escrevendo Excel usando OLEDB .
Exemplo típico:
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\temp\\test.xls;Extended Properties='Excel 8.0;HDR=Yes'"))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand("CREATE TABLE [Sheet1] ([Column1] string, [Column2] string)", conn);
cmd.ExecuteNonQuery();
}
EDIT - Mais alguns links:
A solução comercial, SpreadsheetGear for .NET , fará isso.
Você pode ver exemplos ao vivo do ASP.NET (C # e VB) aqui e baixar uma versão de avaliação aqui .
Isenção de responsabilidade: Eu possuo SpreadsheetGear LLC
Algumas opções que usei:
Se o XLSX for obrigatório: o ExcelPackage é um bom começo, mas morreu quando o desenvolvedor parou de trabalhar nele. O ExML pegou a partir daí e adicionou alguns recursos. O ExML não é uma opção ruim, ainda o estou usando em alguns sites de produção.
Para todos os meus novos projetos, estou usando o NPOI , a porta .NET do Apache POI . O NPOI 2.0 (Alpha) também suporta XLSX.
Uma opção extremamente leve pode ser usar tabelas HTML. Basta criar tags de cabeça, corpo e tabela em um arquivo e salve-o como um arquivo com uma extensão .xls. Existem atributos específicos da Microsoft que você pode usar para estilizar a saída, incluindo fórmulas.
Sei que você pode não estar codificando isso em um aplicativo Web, mas aqui está um exemplo da composição de um arquivo do Excel por meio de uma tabela HTML. Essa técnica pode ser usada se você estiver codificando um aplicativo de console, aplicativo de desktop ou serviço.
Se você estiver criando arquivos do Excel 2007/2010, experimente este projeto de código aberto: https://github.com/closedxml/closedxml
Ele fornece uma maneira orientada a objetos para manipular os arquivos (semelhante ao VBA) sem lidar com os aborrecimentos dos documentos XML. Pode ser usado por qualquer linguagem .NET como C # e Visual Basic (VB).
O ClosedXML permite criar arquivos do Excel 2007/2010 sem o aplicativo Excel. O exemplo típico é a criação de relatórios do Excel em um servidor da web:
var workbook = new XLWorkbook(); var worksheet = workbook.Worksheets.Add("Sample Sheet"); worksheet.Cell("A1").Value = "Hello World!"; workbook.SaveAs("HelloWorld.xlsx");
Você pode usar o ExcelXmlWriter .
Funciona bem.
Você pode realmente querer verificar as classes de interoperabilidade disponíveis em C # (por exemplo, Microsoft.Office.Interop.Excel
você diz não OLE (o que não é esse), mas as classes de interoperabilidade são muito fáceis de usar. Confira a documentação em C # aqui (a Interop for Excel inicia em página 1072 do PDF em C #).
Você pode ficar impressionado se não os tiver experimentado.
Esteja avisado da posição da Microsoft sobre isso:
No momento, a Microsoft não recomenda e não oferece suporte a aplicativos de automação do Microsoft Office de qualquer aplicativo ou componente cliente não interativo e autônomo (incluindo serviços ASP, ASP.NET, DCOM e NT), porque o Office pode exibir um comportamento instável e / ou impasse quando o Office é executado nesse ambiente.
Aqui está um C # biblioteca completamente livre, que permite a exportação a partir de um DataSet
, DataTable
ouList<>
em um arquivo .xlsx Excel 2007 genuína, usando as bibliotecas OpenXML:
http://mikesknowledgebase.com/pages/CSharp/ExportToExcel.htm
O código fonte completo é fornecido - gratuitamente - junto com instruções e um aplicativo de demonstração.
Depois de adicionar esta classe ao seu aplicativo, você pode exportar o DataSet para o Excel em apenas uma linha de código:
CreateExcelFile.CreateExcelDocument(myDataSet, "C:\\Sample.xlsx");
Não fica muito mais simples do que isso ...
E nem sequer exige que o Excel esteja presente no seu servidor.
Você pode criar seus arquivos usando o formato XML Spreadsheet 2003 . Este é um formato XML simples, usando um esquema bem documentado .
Você pode dar uma olhada no GemBox.Spreadsheet .
Eles têm uma versão gratuita com todos os recursos, mas limitados a 150 linhas por folha e 5 folhas por pasta de trabalho, se isso atender às suas necessidades.
Ainda não precisei usá-lo, mas parece interessante.
O Syncfusion Essential XlsIO pode fazer isso. Ele não depende do Microsoft office e também oferece suporte específico para diferentes plataformas.
Exemplo de código:
//Creates a new instance for ExcelEngine.
ExcelEngine excelEngine = new ExcelEngine();
//Loads or open an existing workbook through Open method of IWorkbooks
IWorkbook workbook = excelEngine.Excel.Workbooks.Open(fileName);
//To-Do some manipulation|
//To-Do some manipulation
//Set the version of the workbook.
workbook.Version = ExcelVersion.Excel2013;
//Save the workbook in file system as xlsx format
workbook.SaveAs(outputFileName);
Todo o conjunto de controles está disponível gratuitamente através do programa de licença da comunidade , se você se qualificar (menos de 1 milhão de dólares em receita). Nota: Eu trabalho para o Syncfusion.
Bem,
você também pode usar uma biblioteca de terceiros como o Aspose .
Essa biblioteca tem o benefício de não exigir que o Excel seja instalado em sua máquina, o que seria ideal no seu caso.
O OpenXML também é uma boa alternativa que ajuda a evitar a instalação do MS Excel no servidor.O Open XML SDK 2.0 fornecido pela Microsoft simplifica a tarefa de manipular pacotes Open XML e os elementos subjacentes do esquema Open XML em um pacote. A API (Open XML Application Programming Interface) encapsula muitas tarefas comuns que os desenvolvedores executam nos pacotes Open XML.
Confira isto OpenXML: alternativa que ajuda a evitar a instalação do MS Excel no servidor
As várias bibliotecas XML do Office 2003 disponíveis funcionam muito bem para arquivos excel menores. No entanto, acho que o tamanho de uma grande pasta de trabalho salva no formato XML é um problema. Por exemplo, uma pasta de trabalho com a qual trabalho teria 40 MB no novo formato XLSX (e reconhecidamente mais compactado) se torna um arquivo XML de 360 MB.
Tanto quanto minha pesquisa me levou, existem dois pacotes comerciais que permitem a saída para os formatos de arquivos binários mais antigos. Eles são:
Nem são baratos (500 USD e 800 USD respectivamente, eu acho). mas ambos funcionam independentemente do próprio Excel.
O que eu gostaria de saber é o módulo de saída do Excel para os gostos do OpenOffice.org. Gostaria de saber se eles podem ser portados de Java para .Net.
Concordo em gerar planilhas XML, eis um exemplo de como fazer isso para C # 3 (todo mundo só escreve sobre isso no VB 9: P) http://www.aaron-powell.com/linq-to-xml-to- excel
Recentemente, usei o FlexCel.NET e achei uma excelente biblioteca! Não digo isso sobre muitos produtos de software. Não adianta dar todo o discurso de vendas aqui, você pode ler todos os recursos em seu site.
É um produto comercial, mas você obtém a fonte completa se o comprar. Então, suponho que você possa compilá-lo em sua montagem, se realmente quiser. Caso contrário, é apenas um conjunto extra para o xcopy - sem configuração ou instalação ou algo assim.
Eu não acho que você encontrará nenhuma maneira de fazer isso sem bibliotecas de terceiros, pois o .NET Framework, obviamente, não possui suporte embutido e a Automação OLE é apenas um mundo de dores.
Eu escrevi um código simples para exportar o conjunto de dados para o Excel sem usar o objeto Excel usando System.IO.StreamWriter.
Abaixo está o código que lerá todas as tabelas do conjunto de dados e as escreverá nas planilhas uma a uma. Eu peguei a ajuda deste artigo .
public static void exportToExcel(DataSet source, string fileName)
{
const string endExcelXML = "</Workbook>";
const string startExcelXML = "<xml version>\r\n<Workbook " +
"xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " +
"xmlns:x=\"urn:schemas- microsoft-com:office:" +
"excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" +
"office:spreadsheet\">\r\n <Styles>\r\n " +
"<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " +
"<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" +
"\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" +
"\r\n <Protection/>\r\n </Style>\r\n " +
"<Style ss:ID=\"BoldColumn\">\r\n <Font " +
"x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"StringLiteral\">\r\n <NumberFormat" +
" ss:Format=\"@\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"Decimal\">\r\n <NumberFormat " +
"ss:Format=\"0.0000\"/>\r\n </Style>\r\n " +
"<Style ss:ID=\"Integer\">\r\n <NumberFormat " +
"ss:Format=\"0\"/>\r\n </Style>\r\n <Style " +
"ss:ID=\"DateLiteral\">\r\n <NumberFormat " +
"ss:Format=\"mm/dd/yyyy;@\"/>\r\n </Style>\r\n " +
"</Styles>\r\n ";
System.IO.StreamWriter excelDoc = null;
excelDoc = new System.IO.StreamWriter(fileName);
int sheetCount = 1;
excelDoc.Write(startExcelXML);
foreach (DataTable table in source.Tables)
{
int rowCount = 0;
excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
excelDoc.Write("<Table>");
excelDoc.Write("<Row>");
for (int x = 0; x < table.Columns.Count; x++)
{
excelDoc.Write("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">");
excelDoc.Write(table.Columns[x].ColumnName);
excelDoc.Write("</Data></Cell>");
}
excelDoc.Write("</Row>");
foreach (DataRow x in table.Rows)
{
rowCount++;
//if the number of rows is > 64000 create a new page to continue output
if (rowCount == 64000)
{
rowCount = 0;
sheetCount++;
excelDoc.Write("</Table>");
excelDoc.Write(" </Worksheet>");
excelDoc.Write("<Worksheet ss:Name=\"" + table.TableName + "\">");
excelDoc.Write("<Table>");
}
excelDoc.Write("<Row>"); //ID=" + rowCount + "
for (int y = 0; y < table.Columns.Count; y++)
{
System.Type rowType;
rowType = x[y].GetType();
switch (rowType.ToString())
{
case "System.String":
string XMLstring = x[y].ToString();
XMLstring = XMLstring.Trim();
XMLstring = XMLstring.Replace("&", "&");
XMLstring = XMLstring.Replace(">", ">");
XMLstring = XMLstring.Replace("<", "<");
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write(XMLstring);
excelDoc.Write("</Data></Cell>");
break;
case "System.DateTime":
//Excel has a specific Date Format of YYYY-MM-DD followed by
//the letter 'T' then hh:mm:sss.lll Example 2005-01-31T24:01:21.000
//The Following Code puts the date stored in XMLDate
//to the format above
DateTime XMLDate = (DateTime)x[y];
string XMLDatetoString = ""; //Excel Converted Date
XMLDatetoString = XMLDate.Year.ToString() +
"-" +
(XMLDate.Month < 10 ? "0" +
XMLDate.Month.ToString() : XMLDate.Month.ToString()) +
"-" +
(XMLDate.Day < 10 ? "0" +
XMLDate.Day.ToString() : XMLDate.Day.ToString()) +
"T" +
(XMLDate.Hour < 10 ? "0" +
XMLDate.Hour.ToString() : XMLDate.Hour.ToString()) +
":" +
(XMLDate.Minute < 10 ? "0" +
XMLDate.Minute.ToString() : XMLDate.Minute.ToString()) +
":" +
(XMLDate.Second < 10 ? "0" +
XMLDate.Second.ToString() : XMLDate.Second.ToString()) +
".000";
excelDoc.Write("<Cell ss:StyleID=\"DateLiteral\">" +
"<Data ss:Type=\"DateTime\">");
excelDoc.Write(XMLDatetoString);
excelDoc.Write("</Data></Cell>");
break;
case "System.Boolean":
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.Int16":
case "System.Int32":
case "System.Int64":
case "System.Byte":
excelDoc.Write("<Cell ss:StyleID=\"Integer\">" +
"<Data ss:Type=\"Number\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.Decimal":
case "System.Double":
excelDoc.Write("<Cell ss:StyleID=\"Decimal\">" +
"<Data ss:Type=\"Number\">");
excelDoc.Write(x[y].ToString());
excelDoc.Write("</Data></Cell>");
break;
case "System.DBNull":
excelDoc.Write("<Cell ss:StyleID=\"StringLiteral\">" +
"<Data ss:Type=\"String\">");
excelDoc.Write("");
excelDoc.Write("</Data></Cell>");
break;
default:
throw (new Exception(rowType.ToString() + " not handled."));
}
}
excelDoc.Write("</Row>");
}
excelDoc.Write("</Table>");
excelDoc.Write(" </Worksheet>");
sheetCount++;
}
excelDoc.Write(endExcelXML);
excelDoc.Close();
}
Só quero adicionar outra referência a uma solução de terceiros que lida diretamente com seu problema: http://www.officewriter.com
(Aviso: trabalho para a SoftArtisans, a empresa que fabrica o OfficeWriter)
Aqui está uma maneira de fazer isso com o LINQ to XML, completo com o código de exemplo:
Importe e exporte rapidamente dados do Excel com LINQ to XML
É um pouco complexo, já que você precisa importar espaços para nome e assim por diante, mas permite evitar dependências externas.
(Além disso, é claro, é VB .NET, não C #, mas você sempre pode isolar o material VB .NET em seu próprio projeto para usar XML Literals e fazer todo o resto em C #.)
Alguns fornecedores de componentes de terceiros, como Infragistics ou Syncfusion, oferecem recursos de exportação do Excel muito bons que não exigem a instalação do Microsoft Excel.
Como esses fornecedores também fornecem componentes avançados de grade da interface do usuário, esses componentes são particularmente úteis se você deseja que o estilo e o layout de uma exportação do Excel imitem o estado atual de uma grade na interface do usuário do seu aplicativo.
Se sua exportação se destina a ser executada no lado do servidor, com ênfase nos dados a serem exportados e sem nenhum link para a interface do usuário, eu optaria por uma das opções de código aberto gratuitas (por exemplo, ExcelLibrary).
Eu já participei de projetos que tentaram usar a automação do lado do servidor no pacote Microsoft Office. Com base nessa experiência, eu recomendaria fortemente contra essa abordagem.
public class GridViewExportUtil
{
public static void Export(string fileName, GridView gv)
{
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader(
"content-disposition", string.Format("attachment; filename={0}", fileName));
HttpContext.Current.Response.ContentType = "application/ms-excel";
using (StringWriter sw = new StringWriter())
{
using (HtmlTextWriter htw = new HtmlTextWriter(sw))
{
// Create a form to contain the grid
Table table = new Table();
// add the header row to the table
if (gv.HeaderRow != null)
{
GridViewExportUtil.PrepareControlForExport(gv.HeaderRow);
table.Rows.Add(gv.HeaderRow);
}
// add each of the data rows to the table
foreach (GridViewRow row in gv.Rows)
{
GridViewExportUtil.PrepareControlForExport(row);
table.Rows.Add(row);
}
// add the footer row to the table
if (gv.FooterRow != null)
{
GridViewExportUtil.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());
HttpContext.Current.Response.End();
}
}
}
/// <summary>
/// Replace any of the contained controls with literals
/// </summary>
/// <param name="control"></param>
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())
{
GridViewExportUtil.PrepareControlForExport(current);
}
}
}
}
Olá, esta solução é exportar sua visualização em grade para o seu arquivo Excel. Isso pode ajudá-lo
Você pode criar arquivos Excel bem formatados usando esta biblioteca:
http://officehelper.codeplex.com/documentation
Veja abaixo a amostra:
using (ExcelHelper helper = new ExcelHelper(TEMPLATE_FILE_NAME, GENERATED_FILE_NAME))
{
helper.Direction = ExcelHelper.DirectionType.TOP_TO_DOWN;
helper.CurrentSheetName = "Sheet1";
helper.CurrentPosition = new CellRef("C3");
//the template xlsx should contains the named range "header"; use the command "insert"/"name".
helper.InsertRange("header");
//the template xlsx should contains the named range "sample1";
//inside this range you should have cells with these values:
//<name> , <value> and <comment>, which will be replaced by the values from the getSample()
CellRangeTemplate sample1 = helper.CreateCellRangeTemplate("sample1", new List<string> {"name", "value", "comment"});
helper.InsertRange(sample1, getSample());
//you could use here other named ranges to insert new cells and call InsertRange as many times you want,
//it will be copied one after another;
//even you can change direction or the current cell/sheet before you insert
//typically you put all your "template ranges" (the names) on the same sheet and then you just delete it
helper.DeleteSheet("Sheet3");
}
onde a amostra se parece com isso:
private IEnumerable<List<object>> getSample()
{
var random = new Random();
for (int loop = 0; loop < 3000; loop++)
{
yield return new List<object> {"test", DateTime.Now.AddDays(random.NextDouble()*100 - 50), loop};
}
}
A maneira mais simples e rápida de criar um arquivo do Excel a partir do C # é usar a Open XML Productivity Tool. A Open XML Productivity Tool vem com a instalação do Open XML SDK. A ferramenta faz a engenharia reversa de qualquer arquivo do Excel em código C #. O código C # pode então ser usado para gerar novamente esse arquivo.
Uma visão geral do processo envolvido é:
DesiredLook.xlsx
.DesiredLook.xlsx
e clique no botão Reflect Code próximo à parte superior.
Como um bônus, esse método funciona para qualquer arquivo do Word e do PowerPoint. Como desenvolvedor de C #, você fará alterações no código para atender às suas necessidades.
Eu desenvolvi um aplicativo WPF simples no github que será executado no Windows para esse fim. Há uma classe de espaço reservado chamada GeneratedClass
onde você pode colar o código gerado. Se você voltar uma versão do arquivo, ele gerará um arquivo do Excel como este:
Alguma automação útil do Excel em C #, você pode encontrar no link a seguir.
http://csharp.net-informations.com/excel/csharp-excel-tutorial.htm
Bolton.
Veja exemplos de como criar arquivos do Excel.
Existem exemplos em C # e VB.NET
Ele gerencia arquivos XSL XSLX e CSV Excel.
xls
ouxlsx
um deles). Não é um requisito que exista um programa no seu computador que possa lê-lo (por exemplo, binário).