A primeira seria utilizar um StreamWriter comum para criar um arquivo com extensão ".xls" e utilizar tabulação (\t) e nova linha (\n) para separar colunas e linhas.
Eu fiz isso a princípio, e até consegui abrir o arquivo no Excel, mas há uma forma mais apropriada para fazê-lo. E foi a forma que eu preferi adotar.
No Visual Studio 2008:
Primeiro será preciso adicionar uma referência ao projeto. No "Solution Explorer" clicar em "References" com o botão direito do mouse e clicar em "Add Reference".
Nas abas superiores da janela que abriu vá para a aba "COM".
Na lista de componentes da aba COM procure em "Component Name" por:
Microsoft Excel 12.0 Object Library
OBS.: O '12.0' é referente à versão, então pode não ser esse o número.
Selecione o componente e clique OK.
Próximo passo...
No início da classe em que pretende fazer os métodos do Excel adicionar o namespace Microsoft.Office.Interop.Excel, utilizando a instrução 'using', da seguinte maneira. Exemplo:
using System;
using System.Collection.Generics;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
A partir disso pode-se criar os objetos necessários dentro da classe.
public class Nome_da_classe
{
private Excel.Application excelApp;/*É uma aplicação do Excel, ou seja, inicia o Excel.*/
private Excel.Workbook arq_de_tab;/*É o arquivo de trabalho, que pode conter várias planilhas.*/
private Excel.Worksheet planilha;/*É a planilha de trabalho.*/
private Excel.Range celulas;/*É um objeto utilizado para selecionar uma ou mais células da planilha e trabalhar com elas.*/
.
.
.
}
O construtor da classe que fiz inicia o Excel e cria um arquivo de trabalho.
public class Nome_da_classe
{
private Excel.Application excelApp;
private Excel.Workbook arq_de_trab;
private Excel.Worksheet planilha;
private Excel.Range celulas;
private bool addplanilha = false;/*Atributo que identifica se deve adicionar planilhas ou, caso falso, inserir a primeira.*/
public Nome_da_classe()
{
try
{
excelApp = new Excel.Application();//Inicia o Excel.
arq_de_trab = (Excel.Workbook)excelApp.Workbooks.Add(1);/*Cria um arquivo de trabalho (ainda sem planilhas).*/
}
catch (Exception) { }
}
.
.
.
}
A partir daí é preciso colocar planilhas no arquivo...
eu criei um método para isso, mas precisei de um atributo que me identificasse se eu estou criando a primeira planilha do arquivo ou adicionando planilhas.
public class Nome_da_classe
{
.
.
.
public void NovaPlanilha()
{
try
{
if (addplanilha)
planilha = (Excel.Worksheet)this.excelApp.Worksheets.Add(Type.Missing, Type.Missing, Type.Missing, Type.Missing);
/*Na primeira execução do método ele entrará no 'else', para criar uma nova planilha, a partir da segunda vez ele irá entrar no 'if', para adicionar planilhas.*/
else
{
planilha = (Excel.Worksheet)arq_de_trab.Sheets[1];
addplanilha = true;
}
}
catch (Exception) { }
}
.
.
.
}
A partir daí pode-se utilizar a planilha para jogar valores.
Criei um método de escrita.
public class Nome_da_classe
{
.
.
.
public void Escrever(int linha, int coluna, string texto)
{/*Aqui temos índices para a linha e para a coluna, que começam em '1', diferente de vetores e coleções, onde os índices em geral começam em '0'.*/
try
{
planilha.Cells[linha, coluna] = texto;
}
catch (Exception) { }
}
.
.
.
}
Houve um caso em que eu precisava remover uma linha.
Fiz da seguinte forma.
public class Nome_da_classe
{
.
.
.
public void RemoverLinha(string linha)
{/*Nota: Aqui a linha não pode ser passada por um índice. É preciso passar alguma célula que esteja na linha que se deseja deletar.
Por exemplo: passando a string "A1" por parâmetro no método irá deletar a primeira linha, e "A2" irá deletar a segunda linha.*/
celulas = planilha.get_Range(linha, Type.Missing).EntireRow;
celulas.Delete(Excel.XlDeleteShiftDirection.xlShiftUp);
}
.
.
.
}
Por fim métodos para salvar e sair.
public class Nome_da_classe
{
.
.
.
public void Salvar(string filename)
{
try
{
arq_de_trab.SaveAs(filename, Excel.XlFileFormat.xlExcel7, Type.Missing,
Type.Missing, false, false, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}
catch (Exception) { }
}
public void Sair()
{
try
{
arq_de_trab.Close(false, "", false);
excelApp.Quit();
}
catch (Exception e) { }
}
.
.
.
}
OBS.: É importante executar o 'excelApp.Quit()', pois caso contrário o Excel continuará em execução mesmo que o programa no qual ele foi iniciado seja finalizado.
Quando o método 'Sair()' for utilizado e a instrução 'arq_de_trab.Close(false, "", false)' for executada, o excel irá exibir uma mensagem perguntando se você quer salvar o arquivo (caso você não tenha salvo ele...).
Esse é um problema que pode ser resolvido desativando os alertas. Eu fiz isso no construtor, da seguinte forma.
public class Nome_da_classe
{
.
.
.
public Nome_da_classe()
{
try
{
excelApp = new Excel.Application();
arq_de_trab = (Excel.Workbook)excelApp.Workbooks.Add(1);
excelApp.DisplayAlerts = false;/*Desativa a exibição de alertas do Excel na hora de fechar o arquivo.*/
}
catch (Exception) { }
}
.
.
.
}
Uma última coisa interessante:
Da forma como foi demonstrado, você não verá o arquivo enquanto ele está sendo escrito.
No caso eu não tinha interesse em vê-lo, mas se for o caso pode-se utilizar a propriedade 'excelApp.Visible': colocando 'true' nela o arquivo fica visível.
[update]
Estive revisando os posts aqui do blog e percebi que não mostrei uma forma de ler uma informação de uma célula da planilha. Não é muito complicado. Exemplo prático:
public class Nome_da_classe
{
.
.
.
public string Ler(int linha, int coluna)
{
string resposta = "";
try
{
resposta = ((Excel.Range)planilha.Cells[linha, coluna]).Value2.ToString();
}
catch(Exception e)
{
resposta = "Impossível ler. Erro: " + e.Message;
}
return resposta;
}
.
.
.
}
Cuidado ao ler uma célula. Tenha certeza de que a célula que você vai ler não está vazia, ou você pode acabar gerando uma exceção. O ideal, obviamente, é criar um tratamento para essa exceção, caso ela aconteça.
Um site que foi muito útil especificamente nesse caso de leitura do arquivo:
http://www.sharpprogrammer.com/dotnet/how-to-read-excel-file-in-c-net/
[/update]
[update="18/07/2011"]
Se houver interesse, recentemente fiz um outro post sobre Excel e C#, focado em como abrir uma planilha existente e em algumas observações sobre a leitura de arquivos do Excel.
É possível acessá-lo pelo histórico do blog ou ir pelo link para o post Excel e C#: Abrir uma planilha e ler células.
[/update]
Sites que foram de grande utilidade:
http://www.codeproject.com/KB/cs/Excel_and_C_.aspx?display=Print
http://andylopes.wordpress.com/2008/07/04/gerando_planilha_excel_dotnet/
http://www.daniweb.com/forums/thread210020.html
http://www.dotnetmonster.com/Uwe/Forum.aspx/dotnet-vb/33651/Problem-with-Excel-WorkBook-SaveAs


13 comentários:
Cara, muito maneiro este post, foi muito útil, para mim, parabéns pela sua dedicação para o desenvolvimento do conhecimento!
the future is now
Obrigado, Santi!
O intuito é esse mesmo: desenvolvimento do conhecimento.
Estou sempre aberto a perguntas e sugestões.
Olá
Eu estava mexendo com essas referencias, so que para WORD. e me surgiu um problema... estou usando isso via web. e vi que nao tenho como acessar por la... (teste local funciona pq usa o office instalado na maquina).
O que eu faço, é pegar um modelo do word e com FIND/REPLACE alterar algumas informações... Sabe como poderia fazer isso rodar no servidor (tem como)?
se puder responder por email
alepe86@gmail.com
abrç
Alexandre,
te enviei um e-mail, mas acho que não posso te ajudar nesse caso. Até agora praticamente não trabalhei com aplicações web. Normalmente as questões de referências em webapp são um pouco mais complicadas mesmo e não sei se é possível fazer isso que queres no servidor.
Parabens cara.
Foi bastante útil pra mim esse tutorial.
Abraços.
Muito obrigado, João.
Olá, Ivan. Teria como NÃO colocar o caminho a ser salvo? Tenho que fazer um relatório em excel (lendo os dados do BD), queria que o arquivo fosse aberto para o usuário e que não salvasse o arquivo no servidor.
Sueli
Oi Sueli.
Não entendi exatamente qual é a tua dúvida. Se tu não vais salvar tu não precisas do caminho nem do método para salvar. No caso eu estou editando o arquivo sem exibí-lo, mas tu podes mantê-lo visível inclusive enquanto o edita. Seria esse o caso? Se puderes deixar mais claro o que queres torno a responder. Qualquer coisa podes me mandar uma mensagem.
Obs.: Mesmo quando tu não salvas o arquivo ele é aberto em alguma pasta temporária, obviamente.
Parabéns pela iniciativa,
muito bom o artigo, e o melhor de tudo funciona
Valeu, Henry. :)
Ótimo post, consegui fazer o que estava mais apanhando que era adicionar mais de uma planilha no mesmo arquivo. Porém a única dúvida que tenho é alterar a ordem dessas planilhas dentro do arquivo, pois a Plan2 está vindo antes da Plan1. Alguma sugestão?
Abs. Wellington
mmm
Não cheguei a ter essa necessidade de trabalhar com mais de uma planilha, mas a princípio elas são uma coleção, o que significa que tu pode ordenar elas como tu quiser.
Segundo o que tu falaste deve haver uma lógica em que a última planilha inserida fica na primeira aba da interface visual. Pode ser só uma questão de tu inserir a planilha em um ponto diferente da coleção. Tentaste fazer isso?
Se não for isso avisa aqui no blog que faço uns testes por aqui e aviso o que descobrir.
Bom dia!!
Usei esse código no visual studio e nao criou ficheiro Excel nem nada..
Preciso mesmo de um programa q crie, edite, guarde...
Postar um comentário