Pessoal,
Estou uma dificuldade em gravar o resultado de um query executada em um arquivo txt. Minha query fica num arquivo xml. Até aí consegui ler o xml e guardar essa query em um objeto. Quando passo pro meu ResultSet, não consigo fazer a gravação desses dados buscados pela query no arquivo txt. O meu programa pode executar querys diferentes, não sabendo quais colunas ele irá trazer. Tudo isso depende da query que o caboclo me passou pra configurar no xml.
Usei o getRow() do ResultSet mas só imprimiu a quantidade de linhas lidas na tabela.
Meu método ta assim:
public void executarQuery() throws FileNotFoundException {
BufferedWriter cctoWriter = null;
ResultSet rs = null;
PreparedStatement pstmt = null;
try{
//List<IndicadorBean> indicadores = new ArrayList<IndicadorBean>();
MonitorXmlReader xmlReader = new MonitorXmlReader();
IndicadorBean indicador = xmlReader.parseXmlToObj();
String pSql = indicador.getSql();
File cctoFile = new File("output/report."+indicador.getNomeArquivoSaida()+".txt");
pstmt = this.connection.prepareStatement(pSql);
rs = pstmt.executeQuery();
while(rs.next()){
cctoWriter = new BufferedWriter(new FileWriter(cctoFile));
cctoWriter.write(rs.); //O problema é saber que faço aqui.
cctoWriter.flush();
continue;
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{ if (cctoWriter != null) cctoWriter.close(); }catch(Exception e){}
try{ if (rs != null) rs.close();}catch(Exception e){}
try{ if (pstmt != null) pstmt.close();}catch(Exception e){}
try{ if (this.connection != null) this.connection.close();}catch(Exception e){}}
}
Desde já agradeço a ajuda.
Se dentro do While eu colocar:
System.out.println(lineNumber+" - "+rs.getString(1)+ " | "+rs.getString(2)+ " | "+rs.getString(6)+ " | "+rs.getString(7));
Ele imprime no console todas as linhas tranquilo mas quando tento escrever num arquivo txt, só escreve a última linha.
O único problema do código acima é que a query pode mudar, ou seja, buscando dados de outra tabela e a quantidade de colunas ser diferente. Sendo assim, para uma query que está buscando dados de uma tabela que possui 7 colunas e mudar a query para buscar dados de uma tabela que tenha 5 colunas, dará erro no sistema de nullPointerException pois não existirá a coluna. Estou tentando arrumar um jeito de fazer mas ainda estou com dificuldade.
Obs: lineNumber é apenas um contador de linhas…
Quem puder ajudar, ficarei grato.
Utilize o ResultsetMetaData xD
Ok. To tentando usar esse ResultSetMetaData. Nunca fiz nada com ele. To vendo como posso adaptá-lo ao código que mencionei na 1ª msg.
Fiz aqui mas não ta imprimindo no console corretamente.
O trecho de código ficou assim:
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
while(rs.next()){
lineNumber++;
for(int i=1;i<=numberOfColumns;i++){
//System.out.printf("%-8s\t\n",lineNumber+" - "+rs.getObject(i));
System.out.println(lineNumber+" - "+rs.getString(i));
cctoWriter = new BufferedWriter(new FileWriter(cctoFile));
cctoWriter.write(lineNumber+" - "+rs.getObject(i)+"\n");
cctoWriter.flush();
}
OBS: No código acima criei a linha:
ResultSetMetaData rsmd = null;
E na saída ao invés de imprimir os dados da linha lado a lado, ta saindo dessa forma:
1 - 7866
1 - 2492
1 - C
1 - SDH
1 - Em Operação
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - null
1 - 0
1 - null
1 - null
1 - 1185
1 - migracao
1 - 2006-10-25 00:00:00.0
1 - null
1 - 0
1 - 1
1 - 11032
1 - null
1 - null
1 - null
2 - 7867
2 - 2492
2 - D
2 - SDH
2 - Em Operação
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - null
2 - 0
2 - null
2 - null
2 - 1185
2 - migracao
2 - 2006-10-25 00:00:00.0
2 - null
2 - 0
2 - 1
2 - 11033
2 - null
2 - null
2 - null
Fiz o método aqui mas só tem um problema…quando escreve o resultado da query em um arquivo (xls ou csv ou txt), só escreve a última linha. No console imprime correto, com todas as linhas executadas pela consulta. Estou tentando encontrar qual pode ser o erro mas não estou achando. Quem puder me ajudar, ficarei grato. Segue método:
public void executarQuery() throws FileNotFoundException {
BufferedWriter fileWriter = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
PreparedStatement pstmt = null;
int lineNumber=0;
try{
MonitorXmlReader xmlReader = new MonitorXmlReader();
IndicadorBean indicador = xmlReader.parseXmlToObj();
String pSql = indicador.getSql();
File cctoFile = new File("output/report."+indicador.getNomeArquivoSaida()+System.currentTimeMillis()+".xls");
pstmt = this.connection.prepareStatement(pSql);
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
Vector<Object> rows = new Vector<Object>();
Vector<Object> colunms = new Vector<Object>();
for(int i=1;i<=numberOfColumns;i++)
colunms.add(rsmd.getColumnName(i)+"\t");
System.out.println("-->"+colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\t\n");
while(rs.next()){
lineNumber++;
for(int i=1;i<=numberOfColumns;++i)
rows.add(rs.getString(i)+"\t");
System.out.println(lineNumber+" - "+rows.toString().replace(",", "").replace("[", "").replace("]", ""));
fileWriter = new BufferedWriter(new FileWriter(cctoFile));
fileWriter.write(colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
fileWriter.write(rows.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
fileWriter.flush();
rows.clear();
continue;
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{ if (fileWriter != null) fileWriter.close(); }catch(Exception e){}
try{ if (rs != null) rs.close();}catch(Exception e){}
try{ if (pstmt != null) pstmt.close();}catch(Exception e){}
try{ if (this.connection != null) this.connection.close();}catch(Exception e){}}
}
Alguém teria alguma idéia de onde possa estar a falha, de no momento de eu gravar os dados da consulta numa planilha, só estar gravando a última linha da consulta? No caso deveria gravar todas as linhas da consulta. Alguém tem uma idéia?
Vai debugando e ve se ele não está escrevendo ‘‘por cima’’ dos primeiros registros ^^
[]
Troca esses catch(Exception e){}
Você simplesmente MATA os registros de erro…
Grave em um arquivo de logs ou pelo menos imprima na saída de erro padrão
e.printStackTrace();
ou
[ System.err.println(e.getMessage()); ]
Até estava imaginando que seria isso. Estava debuggando e não me deixou claro que esteja ocorrendo isso. No console imprime corretamente mas na escrita do arquivo, só imprime a última linha, o que deixa a entender que esteja gravando uma linha por cima da outra.
Veja como imprime no console:
-->CARD_INST_ID EQUIP_INST_ID SLOT TYPE STATUS ORDERED DUE INSTALLED IN_SERVICE SCHED_DATE DECOMMISSION SERIAL_NO BATCH_NO BAR_CODE PURCHASE_PRICE PURCHASE_DATE ASSET_LIFE MAXPORTS DESCRIPTION UNEQUIPPED CARD_TPLT_INST_ID LAST_MOD_BY LAST_MOD_TS PARENT_CARD_INST_ID NBR_SUB_CARDS SLOT_OCCUPANCY SLOT_INST_ID DYN_PORT_NAME_GEN_ID ROLE NAME
1 - 7866 2492 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11032 null null null
2 - 7867 2492 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11033 null null null
3 - 7880 2493 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11054 null null null
4 - 7881 2493 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11055 null null null
5 - 7898 2494 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11076 null null null
6 - 7899 2494 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11077 null null null
7 - 7910 2495 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11098 null null null
8 - 7911 2495 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11099 null null null
9 - 7930 2500 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11588 null null null
10 - 7931 2500 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11589 null null null
11 - 7963 2502 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11632 null null null
12 - 7964 2502 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11633 null null null
13 - 7970 2507 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11235 null null null
14 - 7971 2507 D SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11236 null null null
15 - 7985 2508 C SDH Em Operação null null null null null null null null null null null null 0 null null 1185 migracao 2006-10-25 00:00:00.0 null 0 1 11257 null null null
Como são 30 colunas não ficou legal a visualização…
E se você abrisse a conexão com o arquivo e só fechasse depois que imprimir tudo? Acho que fica mais “caro” em termos de processamento ficar abrindo a conexão para cada coluna / linha
Tenta colocar a linha 38 na linha 16 ou 17 ^^
[sei que ja devo ta ficando chato, mas fiquei encucado com este problema, sério rsrs]
E esse continue, na linha 43? O que ele faz?
Fica tranquilo que vc não está sendo chato. Ta ajudando muito.
creio eu que a funcionalidade dele é de abandonarmos a iteração e partirmos para a próxima. Só que tirei ele do meu código e continua gravando somente a última linha, ignorando as demais.
Coloquei as seguintes linhas antes do fileWriter.write():
Iterator it = rows.iterator();
while(it.hasNext())
E escreveu no arquivo pulando de linha em linha, só que somente a primeira linha. Preciso melhorar esse código até que fique ok. Ainda preciso de ajudas…
O código atual ta assim:
public void executarQuery() throws FileNotFoundException {
BufferedWriter fileWriter = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
PreparedStatement pstmt = null;
int lineNumber=0;
try{
MonitorXmlReader xmlReader = new MonitorXmlReader();
IndicadorBean indicador = xmlReader.parseXmlToObj();
String pSql = indicador.getSql();
File indicadorFile = new File("output/report."+indicador.getNomeArquivoSaida()+getDataHora()+".xls");
pstmt = this.connection.prepareStatement(pSql);
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
Vector<Object> rows = new Vector<Object>();
Vector<Object> colunms = new Vector<Object>();
for(int i=1;i<=numberOfColumns;i++)
colunms.add(rsmd.getColumnName(i)+"\t");
System.out.println("-->"+colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\t\n");
while(rs.next()){
lineNumber++;
fileWriter = new BufferedWriter(new FileWriter(indicadorFile));
fileWriter.write(colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
for(int i=1;i<=numberOfColumns;i++)
rows.add(rs.getString(i)+"\t");
System.out.println(lineNumber+" - "+rows.toString().replace(",", "").replace("[", "").replace("]", ""));
Iterator it = rows.iterator(); //Acrescentei essa linha aqui
while(it.hasNext()) //Acrescentei essa linha aqui
fileWriter.write(rows.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
fileWriter.flush();
fileWriter.newLine();
rows.clear();
}
}catch(Exception e){
e.printStackTrace();
}
finally{
try{ if (fileWriter != null) fileWriter.close(); }catch(Exception e){e.printStackTrace();}
try{ if (rs != null) rs.close();}catch(Exception e){e.printStackTrace();}
try{ if (pstmt != null) pstmt.close();}catch(Exception e){e.printStackTrace();}
try{ if (this.connection != null) this.connection.close();}catch(Exception e){e.printStackTrace();}}
}
Alguém poderia dar uma ajuda? Com essa nova linha que acrescentei, obtive uma escrita pulando de linha a linha no arquivo excel. O problema que está imprimindo somente a primeira linha zilhões de vezes. O que pode estar acarretando isso???
Debuggando a aplicação, percebi que realmente está escrevendo uma linha por cima da outra, por isso que ao visualizar o arquivo, só me mostra a ultima linha. Estou tentando encontrar uma maneira de fazer com que escreva linha por linha (pulando a linha). Quem puder dar uma idéia, será bem vinda.
Então, se você puder modificar seu algorítmo um pouco, pode, no lugar de já ir pegando os resultados e gravando no arquivo, vai pegando os resultados e salva em um StringBuilder, depois você grava a String (que contém todas as linhas) de uma vez só 
Não entendi muito bem pois nunca usei o StringBuilder.
Ficou mais ou menos assim:
(não deu pra eu testar, tentei fazer uns Mocks dos seus objetos aqui mas nem dei conta, e também não tenho uma base pronta pra isso…)
[code]public void executarQuery() throws FileNotFoundException {
BufferedWriter fileWriter = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
PreparedStatement pstmt = null;
int lineNumber=0;
try{
MonitorXmlReader xmlReader = new MonitorXmlReader();
IndicadorBean indicador = xmlReader.parseXmlToObj();
String pSql = indicador.getSql();
File cctoFile = new File("output/report."+indicador.getNomeArquivoSaida()+System.currentTimeMillis()+".xls");
pstmt = this.connection.prepareStatement(pSql);
rs = pstmt.executeQuery();
rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
Vector<Object> rows = new Vector<Object>();
Vector<Object> colunms = new Vector<Object>();
//Estou criando o StringBuilder aqui
StringBuilder texto = new StringBuilder();
for(int i=1;i<=numberOfColumns;i++)
colunms.add(rsmd.getColumnName(i)+"\t");
System.out.println("-->"+colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\t\n");
while(rs.next()){
lineNumber++;
for(int i=1;i<=numberOfColumns;++i)
rows.add(rs.getString(i)+"\t");
System.out.println(lineNumber+" - "+rows.toString().replace(",", "").replace("[", "").replace("]", ""));
//Aqui, troca o fileWriter.write por texto.append( ... );
texto.append(colunms.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
texto.append(rows.toString().replace(",", "").replace("[", "").replace("]", "")+"\n");
rows.clear();
//Como já ta no final do lasso, acho que não precisa do continue
}
//Agora que todas as linhas estão em texto, salva no arquivo
fileWriter = new BufferedWriter(new FileWriter(cctoFile));
fileWriter.write(texto.toString());
fileWriter.flush();
}catch(Exception e){
e.printStackTrace();
}
finally{
try{ if (fileWriter != null) fileWriter.close(); }catch(Exception e){}
try{ if (rs != null) rs.close();}catch(Exception e){}
try{ if (pstmt != null) pstmt.close();}catch(Exception e){}
try{ if (this.connection != null) this.connection.close();}catch(Exception e){}}
}[/code]
Perfeito meu brother!
Só alterei duas linhas pra não ficar gravando linha/coluna, linha/coluna, etc…Agora ta show!
Valeu!!! Muito obrigado mesmo.