Html 2 pdf -> bd

Pessoal,

Tenho a seguinte situação:

Tenho um campo text no banco postgresql que contém o conteúdo de um campo textarea com fckeditor, ou seja, o conteúdo é HTML.

Após concluir o trabalho, queria pegar esse conteúdo do banco, transformar em pdf e inserir em outra coluna do tipo bytea (binário).

Peguei alguns exemplos usando iText e Flying-Saucer, mas não tô conseguindo criar esse pdf em memória e depois inserir no banco.

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringBufferInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.tidy.Tidy;
import org.xhtmlrenderer.pdf.ITextRenderer;

import br.com.itx.database.impl.ConnectionSql;
import br.com.itx.exception.UserException;
import br.com.itx.integration.AbstractConnector;
import br.com.itx.integration.DatabaseAliases;
import br.com.itx.integration.DatabaseHandler;
import br.com.itx.integration.InterfaceHeaders;
import br.com.itx.util.WIMap;

import com.itextpdf.text.DocumentException;

public class TransformarHtml2Pdf extends AbstractConnector {

	DatabaseHandler dthd;
	ConnectionSql csql;
	Connection conn;
	String query, conteudo;
	ResultSet rset;
	PreparedStatement pstm;
	
	public void execute(WIMap arg0, DatabaseAliases arg1, InterfaceHeaders arg2) throws UserException {
		try{
                 //Pega conexão do WI
	  	 dthd = arg1.get("adebd");
                 csql = (ConnectionSql) dthd.getDatabaseConnection();
                 conn = csql.getConnection();
                //Prepara a consulta
                query = "SELECT ARQUIVO FROM DOCUMENTO WHERE ID_DOCUMENTO = ?";
                pstm = conn.prepareStatement(query);
                pstm.setInt(1, 157); //Pega o id_documento como parâmetro
                rset = pstm.executeQuery();
                rset.next();
                conteudo = rset.getString(1);
                //Transforma HTML em PDF
                StringBuffer buf = new StringBuffer(conteudo);
                DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
                Document doc = builder.parse(new StringBufferInputStream(buf.toString()));
                ITextRenderer renderer = new ITextRenderer();
                renderer.setDocument(doc, null);
                renderer.layout();

                #MINHA DÚVIDA ESTÁ AQUI, COMO PEGAR O CONTEÚDO HTML, TRANSFORMAR EM PDF E JOGAR NO BD. 

		} catch(Exception e){
			e.printStackTrace();
		}
	}
}

Sds, Luciano.

esse código não funcionou?

Ele tá incompleto, esse é meu problema, não tô sabendo como pegar e jogar no banco como arquivo pdf o conteúdo html que busquei no código.

vc ta conseguindo gerar o pdf?

Não tentei, pois não quero gerar pdf em máquina, é uma aplicação web, então, depois que a pessoa clicar em determinado botão, quero pegar esse html e transformar em pdf e jogar o pdf no banco sem a necessidade de criar um pdf no servidor e depois pegar esse arquivo e fazer o upload no banco, queria algo automático.

hum, entendo. Não testei, mas vc não poderia passar um ByteArrayOutputstream para montar o pdf, e depois pegar esses bytes pra gravar diretamente no seu banco?

ou ainda, vc não poderia gravar o html e depois no momento de mandar para o usuário, ai vc transforma em pdf?

creio que uma dessas duas opções deve resolver seu problema.

É isso que eu não estou sabendo fazer, teria como passar um exemplo?

amanhã eu entro e te passo, to sem java na minha maquina de casa.

[]'s

Aqui vai. Não testei nada, qq coisa posta ai.

[code]
//Cria o outputStream
ByteArrayOutputStream out = new ByteArrayOutputStream();

	//Transforma HTML em PDF
    StringBuffer buf = new StringBuffer(conteudo);
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document doc = builder.parse(new StringBufferInputStream(buf.toString()));
    ITextRenderer renderer = new ITextRenderer();
    renderer.setDocument(doc, null);
    renderer.layout();
	renderer.createPDF(out);
	
	// nesse ponto, o conteudo do pdf ta no out. Vamos transformar 
	// em um arrayde bytes e gravar num campo blob do banco
	
	byte[] content = out.toByteArray();
	
	//abre conexão, stmt, e bla bla bla. 
	//em um ponto vc vai setar o array no stmt, ai vc vai ter q ver qual jeito funciona pra vc
	stmt.setBytes(index, content);
	//ou
	stmt.setBinaryStream(index, new ByteArrayInputStream(content),content.length);
	// se vc estiver usando java 6, na connection tem um método createBlob(), usa ele pra 
	// criar o blob e seta o conteudo do array nele e sepois usa o setBlob do stmt.[/code]

[]'s

Acho que estamos quase lá, veja um código de exemplo:

package br.jus.tjba;

import java.io.ByteArrayOutputStream;
import java.io.StringBufferInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;

import br.com.itx.database.impl.ConnectionSql;
import br.com.itx.integration.DatabaseHandler;

public class TransformarHtml2PdfMain {
	
	public static void main(String args[]){
		
		String query, conteudo;
		Connection con;
		ResultSet rset;
		PreparedStatement pstm;
		ITextRenderer renderer = new ITextRenderer();
		ByteArrayOutputStream out;
        StringBuffer buf;
        DocumentBuilder builder;
        Document doc;
        
		
		try {
			Class.forName("org.postgresql.Driver");
			con = DriverManager.getConnection("jdbc:postgresql://10.10.2.191:5432/addb","addbuser","teste01");
			//Prepara a consulta
	         query = "SELECT ARQUIVO FROM DOCUMENTO WHERE ID_DOCUMENTO = ?"; // a coluna arquivo é o html
	         pstm = con.prepareStatement(query);
	         pstm.setInt(1, 157); //Pega o id_documento como parâmetro
	         rset = pstm.executeQuery();
	         rset.next();
	         conteudo = rset.getString(1);
	         //Transforma HTML em PDF
	         out = new ByteArrayOutputStream();
	         buf = new StringBuffer(conteudo);
	         builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
	         doc = builder.parse(new StringBufferInputStream(buf.toString()));
	         renderer.setDocument(doc, null);
	         renderer.layout();
	         renderer.createPDF(out);     
	         byte[] content = out.toByteArray();
	         query = "UPDATE DOCUMENTO SET BINARIO = ? WHERE ID_DOCUMENTO = ?";
	         pstm = con.prepareStatement(query);
	         pstm.setBytes(1, content);
	         pstm.setInt(2, 157); //Pega o id_documento como parâmetro
	         pstm.executeUpdate();
	         rset.close();
	         pstm.close();
	         con.close();
		} catch(Exception e){
			e.printStackTrace();
		}
	}
}

Quando rodo dessa forma, acontece o seguinte erro:

[color=red][Fatal Error] :1:62: White spaces are required between publicId and systemId.
org.xml.sax.SAXParseException: White spaces are required between publicId and systemId.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)[/color]

Dei uma pesquisada rápida na net e mandaram tirar a tag:

<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN”>

do texto, fiz e ao rodar aconteceu o seguinte erro:

[color=red]com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 2 of 2-byte UTF-8 sequence.
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.invalidByte(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.io.UTF8Reader.read(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.load(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityScanner.skipChar(Unknown Source)[/color]

O erro fatal ocorre na linha abaixo, mas a classe compila normal.

doc = builder.parse(new StringBufferInputStream(buf.toString()));

Sds, Luciano

Quando eu coloco um HTML simples, funciona beleza, agora quando coloco um HTML complexo (que veio do fckeditor), dá as broncas acimas.

conseguiram resolver o problema??

aparentemente o ckeditor coloca umas tags do word, ai junta com as do html e zaz…

enfim, aqui está dando erro por causa disso!

alguém encontrou uma solução???