Download de planilha excel [RESOLVIDO]

Pessoal,

Eu estou gravando um arquivo excel no servidor… e estou tentando usar o

response.setHeader("Content-Disposition", "attachment; filename=./arquivoUpload/Consulta_Coletiva - "+formatador.format(calendar.getTime())+".xls");

Para a pessoal fazer o download… só que não consigo. o arquivo vem em branco, e eu olhei no servidor no diretório aquivoUpload, e ele foi criado lá…

alguem sabe alguma idéia de como fazer uma opção de download par ao cliente? acessando esse diretório do servidor/??

se o arquivo está lá, tem certeza que você está apontando pro caminho certo?

tenho… o arvui esta la… só não sei se o problema está nesse jeito que estou usando o response… só que nem imagino uma solução

Você não precisa salvar o arquivo no servidor para que o cliente faça o download. Se estiver usando o POI, ele permite que você transfira direto para a saída do servlet:

 HSSFWorkbook wb = new HSSFWorkbook();
 HSSFSheet sheet = wb.createSheet("new sheet");
 ...
 OutputStream out = response.getOutputStream();
 wb.write(out);
 out.close();

Agora se a planilha não for produzida pelo POI, você terá que ler o arquivo por um FileInputStream e escreve byte-a-byte na saída do servlet.

to usando o jxecel

Segue um exemplo do site do JExcel de como escrever uma planilha direto para a saída:

import java.io.IOException;
	import java.io.OutputStream;
	 
	import javax.servlet.ServletException;
	import javax.servlet.http.HttpServlet;
	import javax.servlet.http.HttpServletRequest;
	import javax.servlet.http.HttpServletResponse;
	 
	import jxl.Workbook;
	import jxl.write.Label;
	import jxl.write.WritableSheet;
	import jxl.write.WritableWorkbook;
	 
	public class Sample extends HttpServlet
	{
	 public void doGet(HttpServletRequest request, HttpServletResponse response)
	 throws ServletException, IOException
	 {
	  OutputStream out = null;
	  try
	  {
	   response.setContentType("application/vnd.ms-excel");
	   response.setHeader("Content-Disposition", "attachment; filename=sampleName.xls");
	   WritableWorkbook w = Workbook.createWorkbook(response.getOutputStream());
	   WritableSheet s = w.createSheet("Demo", 0);
	   s.addCell(new Label(0, 0, "Hello World"));
	   w.write();
	   w.close();
	  } catch (Exception e)
	  {
	   throw new ServletException("Exception in Excel Sample Servlet", e);
	  } finally
	  {
	   if (out != null)
	    out.close();
	  }
	 }
	}

Valeu vinicius… mas no meu caso tenho que fazer assim separado, pois eu fico chamando métodos para preencher a planilha… não é só uma vez que entro na classe para gerar o arquivo…

Então vai ter que usar a estratégia que te falei: criar um FileInputStream passando o arquivo xls gerado, obter os bytes do arquivo e escrevê-los na output stream da response. É assim que está fazendo?

segue minha classe de criar excel… eu pego o arquivo vindo de um jsp passo para o sevlet o arquivo que será pego uns valores para realizar uma consulta no BD.

File uploadedFile = new File("./arquivoUpload/"
									+ fileItem.getName());
							fileItem.write(uploadedFile);
							caminho = "./arquivoUpload/" + fileItem.getName();

Esse arquivo gravo no servidor, para poder ler e chamo a classe criar excel


package br.com.simcard;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;

import org.apache.commons.fileupload.FileUploadException;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.Colour;
import jxl.read.biff.BiffException;
import jxl.write.Label;
import jxl.write.WritableCellFormat;
import jxl.write.WritableFont;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;
	  
	public class CriarExcel {   
	  
	    /*public static void main(String[] args) {   
	        try{   
	            CriarPlanilha();   
	            System.out.println("Planilha escrita com sucesso");   
	        } catch (NullPointerException npe){   
	            npe.printStackTrace();   
	        } catch (IOException ioe){   
	            ioe.printStackTrace();   
	        } catch (RowsExceededException ree){   
	            ree.printStackTrace();   
	        } catch (WriteException we){   
	            we.printStackTrace();   
	        }   
	    }*/   

		
	    public void CriarPlanilhaColetiva(String dispositivo, String codTecnologia, String apnConfigurada, String simCard,
	    		String linha, String operadora, String apnProvisionada, String statusSIMCard, String fonte, String imei,
	    		String imsi, String statusLinha, String consDados, String matricula) throws IOException, RowsExceededException, WriteException, BiffException{   
	        
	    	//FORMATANDO FONTE
	    	// Adicionando formato de fonte no título... se adicionar ", true" depois de bold adiciona Italico	    	
	    	WritableFont bold = new WritableFont(WritableFont.ARIAL,                 
	    	10, WritableFont.BOLD);         
	    	bold.setColour(Colour.WHITE);         
	    	WritableCellFormat arial10font = new WritableCellFormat(bold);         
	    	arial10font.setBackground(Colour.BLUE);         
	    	arial10font.setAlignment(Alignment.CENTRE);     
	    	arial10font.setBorder(Border.ALL,BorderLineStyle.MEDIUM,Colour.BLACK); 
	    	
	    	// Adicionando formato de fonte resultados... se adicionar ", true" depois de bold adiciona Italico	    	
	    	WritableFont bold2 = new WritableFont(WritableFont.ARIAL, 10);         
	    	WritableCellFormat arial10fontResult = new WritableCellFormat(bold2);         
	    	arial10fontResult.setAlignment(Alignment.CENTRE);         
	    	arial10fontResult.setBorder(Border.ALL,BorderLineStyle.THIN,Colour.BLACK); 
	    	   	
	    	//ADICIONA DATA/HORA NO ARQUIVO GERADO
	    	GregorianCalendar calendar = new GregorianCalendar();   
	        SimpleDateFormat formatador = new SimpleDateFormat("dd' de 'MMMMM' de 'yyyy");     
	        System.out.println(formatador.format(calendar.getTime()));   
	           
	        String filename = "./arquivoUpload/Consulta_Coletiva - "+formatador.format(calendar.getTime())+".xls"; 
	    	File filename2 = new File(filename);
	        
	    	if (!filename2.exists()){
	    	
	    	//Instanciando a classe q gera o novo arquivo do Excel   
	        WritableWorkbook workbook = Workbook.createWorkbook(new File(filename));   
	           
	        //Criando uma nova planilha   
	        WritableSheet sheet = workbook.createSheet("First Sheet", 0);
	        
	        
        	//col, lin
	        Label labelTitulo0 = new Label(0, 0, "Dispositivo", arial10font);   
	        sheet.addCell(labelTitulo0);
	        
	        Label labelTitulo1 = new Label(1, 0, "SIMCard", arial10font);   
	        sheet.addCell(labelTitulo1);
	        
	        Label labelTitulo2 = new Label(2, 0, "Linha", arial10font);   
	        sheet.addCell(labelTitulo2);
	        
	        Label labelTitulo3 = new Label(3, 0, "Tecnologia", arial10font);   
	        sheet.addCell(labelTitulo3);
	        
	        Label labelTitulo4 = new Label(4, 0, "APN Configurada", arial10font);   
	        sheet.addCell(labelTitulo4);
	        
	        Label labelTitulo5 = new Label(5, 0, "Operadora", arial10font);   
	        sheet.addCell(labelTitulo5);
	        
	        Label labelTitulo6 = new Label(6, 0, "APN Provisionada", arial10font);   
	        sheet.addCell(labelTitulo6);
	        
	        Label labelTitulo7 = new Label(7, 0, "Status SIMCard", arial10font);   
	        sheet.addCell(labelTitulo7);
	        
	        Label labelTitulo8 = new Label(8, 0, "Fonte", arial10font);   
	        sheet.addCell(labelTitulo8);
	        
	        Label labelTitulo9 = new Label(9, 0, "IMEI", arial10font);   
	        sheet.addCell(labelTitulo9);
	        
	        Label labelTitulo10 = new Label(10, 0, "IMSI", arial10font);   
	        sheet.addCell(labelTitulo10);
	        
	        Label labelTitulo11 = new Label(11, 0, "Status Linha", arial10font);   
	        sheet.addCell(labelTitulo11);
	        
	        Label labelTitulo12 = new Label(12, 0, "Consumo de Dados", arial10font);   
	        sheet.addCell(labelTitulo12);
	        
	        Label labelTitulo13 = new Label(13, 0, "Matricula", arial10font);   
	        sheet.addCell(labelTitulo13);
	        
	        int i = sheet.getRows();
	        
        	//col, lin
	        Label label = new Label(0, i, dispositivo, arial10fontResult);   
	        sheet.addCell(label);
	        
	        Label label1 = new Label(1, i, simCard, arial10fontResult);   
	        sheet.addCell(label1);
	        
	        Label label2 = new Label(2, i, linha, arial10fontResult);
	        sheet.addCell(label2);
	        
	        Label label3 = new Label(3, i, codTecnologia, arial10fontResult);
	        sheet.addCell(label3);
	        
	        Label label4 = new Label(4, i, apnConfigurada, arial10fontResult);
	        sheet.addCell(label4);
	        
	        Label label5 = new Label(5, i, operadora, arial10fontResult);
	        sheet.addCell(label5);
	        
	        Label label6 = new Label(6, i, apnProvisionada, arial10fontResult);
	        sheet.addCell(label6);
	        
	        Label label7 = new Label(7, i, statusSIMCard, arial10fontResult);
	        sheet.addCell(label7);
	        
	        Label label8 = new Label(8, i, fonte, arial10fontResult);
	        sheet.addCell(label8);
	        
	        Label label9 = new Label(9, i, imei, arial10fontResult);
	        sheet.addCell(label9);
	        
	        Label label10 = new Label(10, i, imsi, arial10fontResult);
	        sheet.addCell(label10);
	        
	        Label label11 = new Label(11, i, statusLinha, arial10fontResult);
	        sheet.addCell(label11);
	        
	        Label label12 = new Label(12, i, consDados, arial10fontResult);
	        sheet.addCell(label12);
	        
	        Label label13 = new Label(13, i, matricula, arial10fontResult);
	        sheet.addCell(label13);
	        
	           
	        // Escrevedo o arquivo em disco   
	        workbook.write();   
	           
	        // Fechando a IO   
	        workbook.close();   
	    	
        
	    	} else {
	    		
	    		Workbook rw = Workbook.getWorkbook (new File (filename2.toString())); 
	    		WritableWorkbook wwb = Workbook.createWorkbook (new File (filename2.toString()), rw);    
		        
	    		
	    		WritableSheet sheet = wwb.getSheet (0); 

	    		
	    		int i = sheet.getRows();
		        
	        	//col, lin
		        Label label = new Label(0, i, dispositivo, arial10fontResult);
		        sheet.addCell(label);
		        
		        Label label1 = new Label(1, i, simCard, arial10fontResult);
		        sheet.addCell(label1);
		        
		        Label label2 = new Label(2, i, linha, arial10fontResult);
		        sheet.addCell(label2);
		        
		        Label label3 = new Label(3, i, codTecnologia, arial10fontResult);
		        sheet.addCell(label3);
		        
		        Label label4 = new Label(4, i, apnConfigurada, arial10fontResult);
		        sheet.addCell(label4);
		        
		        Label label5 = new Label(5, i, operadora, arial10fontResult);
		        sheet.addCell(label5);
		        
		        Label label6 = new Label(6, i, apnProvisionada, arial10fontResult);
		        sheet.addCell(label6);
		        
		        Label label7 = new Label(7, i, statusSIMCard, arial10fontResult);
		        sheet.addCell(label7);
		        
		        Label label8 = new Label(8, i, fonte, arial10fontResult);
		        sheet.addCell(label8);
		        
		        Label label9 = new Label(9, i, imei, arial10fontResult);
		        sheet.addCell(label9);
		        
		        Label label10 = new Label(10, i, imsi, arial10fontResult);
		        sheet.addCell(label10);
		        
		        Label label11 = new Label(11, i, statusLinha, arial10fontResult);
		        sheet.addCell(label11);
		        
		        Label label12 = new Label(12, i, consDados, arial10fontResult);
		        sheet.addCell(label12);
		        
		        Label label13 = new Label(13, i, matricula, arial10fontResult);
		        sheet.addCell(label13);
		        

		        // Escrevedo o arquivo em disco   
		        wwb.write();   
		           
	        
		        // Fechando a IO   
		        wwb.close();
	    		
	    	}
	    	
	    }   
	    
	}
	     

Depois de ler o arquivo, verifica se o caminho dele está correto (ou seja, se o arquivo existe). Se ele existir, seu código para colocá-lo na saída é algo parecido com esse:

        FileInputStream fis = null;
        try {
            // buffer para leitura do arquivo.
            byte[] fileData = new byte[FILE_BUFFER_SIZE];
            fis = new FileInputStream(excelFile);
            response.setContentType("application/vnd.ms-excel; charset=iso-8859-1"); 
            response.setContentLength(fis.available());
            response.setHeader("Content-Disposition", "attachment; filename=\"" + userFileName + "\"");
            
            int bytesRead = 0;
            // lê o arquivo e o escreve na stream da resposta HTTP em seguida.
            while ((bytesRead = fis.read(fileData)) != -1) {
                response.getOutputStream().write(fileData, 0, bytesRead);
            }
            response.getOutputStream().flush();
        } catch (SocketException ex) {
        } catch (SSLException ex) {
        } finally {
            try {
                fis.close();
                response.getOutputStream().close();
                // remove o arquivo da máquina servidora
                pdfFile.delete();
            } catch (SocketException ex) {
            } catch (SSLException ex) {
            }
        }

Valeu vinicius mais uma vez pela ajuda… estou de saída e amanhã realizarei alguns testes com essas dicas…

muito obrigado mesmo…

Cara, ainda não consegui adaptar…

mas vamos tentando…

Qual o problema? Tá recebendo alguma exception?

Não… não estou conseguindo adaptar para meu código…

por exemplo, eu adiciono isso no servlet?

o que coloco neese FILE_BUFFER_SIZE??

Tento fazer esse método mas da erro…

[code]
public void exemplo1 (String arquivo, HttpServletResponse response) throws IOException{

File file = new File(arquivo);   
InputStream in = new FileInputStream(file);   
OutputStream out = response.getOutputStream();   
  
int lengthFile = in.available();   
int length = (lengthFile > 2048) ? 2048 : lengthFile;   
byte[] cache = new byte[length];   
  
response.setContentLength(lengthFile);   
// aqui tem que indicar qual o mime-type do seu arquivo.   
response.setContentType("application/vnd.ms-excel");   
// indica o nome do arquivo.   
response.setHeader("Content-Disposition", "filename=" + file.getName());   
  
// escreve o arquivo na OutputStream do Servlet.   
while(in.read(cache) != -1) {   
  out.write(cache);   
  out.flush();   
}   
in.close();   
out.close();  

}[/code]

java.lang.IllegalStateException: getWriter() has already been called for this response

Na OutputStream out = response.getOutputStream();

Você escreve algo na saída antes deste método? Provavelmente o erro é esse.

Mas essa é a maneira corrate de chamar o download???

eu chamo o método no servlet ou na classe que cria o excel…?

O correto seria utilizar o servlet, para não misturar conceitos de web (como os cabeçalhos da response) com detalhes da geração da planilha em si. Cada classe deve ter a sua responsabilidade. A responsabilidade do servlet é de colocar o conteúdo (bytes) na sua saída para o usuário. A classe de geração do relatório deve gerar esse conteúdo.

Vinicius, muito obrigado pelas dicas… mas to apanhando muito… ja coloquei no Servlet e tal e nada… não sei como mesmo, to lendo em vários lugares, mas to apanhando dos conceitos…