C# e Excel

Em 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.