C# e Excel
27 Jul 2015Em muitas aplicações corporativas (e até algumas fora desta categoria) existe a necessidade de exportar os dados, que na maioria das vezes é em um arquivo PDF ou em uma planilha Excel. Tô mentindo?
Vamos exportar algumas coisas para o Excel hoje?
A solução
A Microsoft disponibiliza uma série de Assemblies para você realizar esta integração entre sua aplicação e as ferramentas do Office, neste link (inglês) você pode ver toda a gama de Assemblies disponíveis, como Word, Visio, Excel, PowerPoint, Outlook, etc. Nosso foco estará no Assembly Microsoft.Office.Interop.Excel.dll, que tem tudo o que é preciso para criar/editar planilhas do Excel.
A estrutura
Para lidarmos com o Excel em nosso código, temos as seguintes partes: Application, WorkBook e WorkSheet.
O Application é o Excel propriamente dito. O WorkBook seria o arquivo que iremos trabalhar, ele pode ser um totalmente novo ou um arquivo no disco rígido. E finalmente o WorkSheet, que são as várias planilhas que o Excel permite ter em um único arquivo.
Então basicamente abrimos um Application, depois abrimos um WorkBook novo ou um arquivo existente, e manipulamos as células do WorkSheet.
Notas
O Excel 12.0 é a versão que está instalada na minha máquina no momento, dependendo da sua versão do Office o número pode mudar, então dê uma atenção nisto quando for adicionar a referência ao projeto.
Outro detalhe: é necessário que tenha o Excel instalado na máquina para funcionar corretamente, pois por trás dos panos, o Assembly que citei abre o Excel escondido (ou não, dependendo do que você precisar) e manipula a planilha de acordo com o que você codificar. Então sem Excel, sem exportação.
Mão na massa
Para este exemplo eu criei um projeto do tipo Console Application (não precisamos de muito, nem de interface gráfica).
O primeiro passo é adicionar a referência do Microsoft Excel Object Library em nosso projeto. No Solution Explorer, você pode ver a estrutura do projeto e nela tem um item chamado References, clique com o botão direito do mouse e depois em Add Reference.
Na janela para escolher a refência, procure a opção COM do lado esquerdo e depois em Type Libraries. Agora procure por Microsoft Excel 12.0 Object Library na lista de referências, como na imagem abaixo.
Assim que clicarmos em Ok, a lista de referências de nosso projeto deve estar semelhante à imagem abaixo.
O namespace que apareceu é Microsoft.Office.Interop.Excel, mas note que também foi adicionado automaticamente o namespace Microsoft.Office.Core pois deve haver código comum para as outras soluções do Office.
Agora vamos pro código! Para facilitar, vou colocar um alias no namespace do Excel (deixará o código mais legível):
using Excel = Microsoft.Office.Interop.Excel;
Para "abrirmos" o Excel, precisamos criar uma instância da Microsoft.Office.Interop.Excel.Application ou Excel.Application com o nosso alias:
namespace ExportaExcel
{
class Program
{
static void Main(string[] args)
{
Excel.Application app = new Excel.Application();
}
}
}
Em alguns casos a máquina que estiver executando sua aplicação pode não ter o Excel instalado, e para saber se está nesta situação basta verificar se a variável app é nula.
if (app == null)
{
Console.WriteLine("O Excel não foi encontrado");
Console.ReadKey();
return;
}
O próximo passo é obter o WorkBook (lembra da estrutura?) e no caso iremos criar um novo WorkBook.
Excel.Workbook workBook = app.Workbooks.Add();
Neste ponto, temos o Excel "aberto" (mas não visível) com um WorkBook ativo (um arquivo novo) e 3 planilhas que é o padrão do Excel.
Antes de mostrar como editar as células e fazer o Excel realmente aparecer na tela, vou mostrar como liberar o Excel. O código abaixo é de extrema importância pois caso você não o coloque, o Excel não irá aparecer, mas ficará na lista de processos do seu computador (você poderá ver pelo Gerenciador de Tarefas).
Para liberarmos o Excel, é necessário fechar o WorkBook, executar o comando Quit do Excel.Application, e liberar o recurso dos dois.
workBook.Close(false);
app.Quit();
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(app);
workBook = null;
app = null;
Nota: a classe Marshal é do namespace System.Runtime.InteropServices.
Agora que temos uma "segurança" no uso do Excel, basicamente temos o seguinte código:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExportaExcel
{
class Program
{
static void Main(string[] args)
{
Excel.Application app = new Excel.Application();
if (app == null)
{
Console.WriteLine("O Excel não foi encontrado");
Console.ReadKey();
return;
}
Excel.Workbook workBook = app.Workbooks.Add();
workBook.Close(false);
app.Quit();
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(app);
workBook = null;
app = null;
}
}
}
Se executar este projeto, não vai acontecer nada e também pode verificar o Gerenciador de Tarefas e ver que o Excel não ficou lá.
Agora vamos ver como mostrar o Excel na tela. Logo abaixo do comando app.Workbooks.Add(), digite o seguinte:
app.Visible = true;
Console.ReadKey();
Isto irá mostrar o Excel e só irá fechá-lo quando você pressionar uma tecla no nosso programa. Você pode fazer um teste: executar o projeto e ver que mostrou o Excel, e com o Excel aberto, pressionar qualquer tecla no programa, o Excel vai fechar. Isso mostra que o controle é nosso.
Para editar as células precisamos ter acesso a uma WorkSheet, então usamos a propriedade Worksheets do nosso WorkBook.
Excel.Worksheet workSheet = workBook.Worksheets[1];
E sim, o índice das planilhas e células começam no um e não no zero.
Bom, uma WorkSheet tem uma propriedade chamada Cells, com ela, podemos acessar a célula através do número da linha e da coluna. No exemplo abaixo realizamos o acesso à célula B3 do Excel.
workSheet.Cells[3, 2] = "João";
Uma outra maneira de acessar as células, é utilizando a propriedade Range que está em Cells. O interessante desta técnica, é que podemos usar faixas de células, por exemplo de A1 até A3 e colocar qualquer valor. No exemplo abaixo, estamos colocando "Vitor" em 5 linhas da coluna A.
workSheet.Cells.Range["A1", "A5"].Value = "Vitor";
Para finalizar, o código completo.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ExportaExcel
{
class Program
{
static void Main(string[] args)
{
Excel.Application app = new Excel.Application();
if (app == null)
{
Console.WriteLine("O Excel não foi encontrado");
Console.ReadKey();
return;
}
Excel.Workbook workBook = app.Workbooks.Add();
Excel.Worksheet workSheet = workBook.Worksheets[1];
workSheet.Cells[3, 2] = "João";
workSheet.Cells.Range["A1", "A5"].Value = "Vitor";
app.Visible = true;
Console.ReadKey();
workBook.Close(false);
app.Quit();
Marshal.ReleaseComObject(workSheet);
Marshal.ReleaseComObject(workBook);
Marshal.ReleaseComObject(app);
workSheet = null;
workBook = null;
app = null;
}
}
}
Conclusão
O que foi mostrado é apenas o princípio da manipulação de planilhas do Excel, em outro post posso mostrar como colocar negrito nas células, salvar o arquivo .XLS, abrir um arquivo, etc.
Criei um repositório no GitHub para quem quiser fazer o download do projeto ou até contribuir se houver algum erro (pode acontecer né).
É interessante dar uma boa olhada na documentação do namespace Microsoft.Office.Interop.Excel (que não é pequena), assim dá até para ir fazendo alguns experimentos.
Até mais.