Converta HTML para PDF com 06 linhas de Código
Sempre vejo pessoas procurando por ai como converter HTML para PDF, mas sempre as soluções são obscuras complicadas e não muito "limpas", as vezes requerendo bibliotecas proprietárias.
Pois então vou lhe dar uma solução com apenas 06 linhas de código que salvará sua alma :+D. Lá vamos nós rápidos e rasteiros. Como o código é mediocremente pequeno vou colocar tudo aqui pra encher linguiça, até os imports
Se você contar o numero de linhas do 2º método convert, verá que há apenas 06 linhas como prometido, e para usar esta classe, o código é menor ainda:
Os jars que vc precisa são estes
Tidy : http://jtidy.sourceforge.net
XHTMLRenderer : https://xhtmlrenderer.dev.java.net/
Itext: http://www.lowagie.com/iText
A beleza do código, você não precisa se preocupar com as coisas baixas, basta mandar HTML em não conformidade que o resto o código cuida.
Espero que tenham divertido-se.
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.w3c.dom.Document;
import org.w3c.tidy.Tidy;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.lowagie.text.DocumentException;
/**
* @Autor Eder Baum
*/
public class Html2Pdf {
public static void convert(String input, OutputStream out) throws DocumentException{
convert(new ByteArrayInputStream(input.getBytes()), out);
}
public static void convert(InputStream input, OutputStream out) throws DocumentException{
Tidy tidy = new Tidy();
Document doc = tidy.parseDOM(input, null);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(doc, null);
renderer.layout();
renderer.createPDF(out);
}
}OutputStream os = new FileOutputStream("C:\\hello.pdf");;
Html2Pdf.convert("<h1 style=\"color:red\">Hello PDF</h1>", os);
os.close();Ederbaum
Curtidas 0
Melhor post
Ederbaum
01/06/2016
Pessoal, o código original fui eu que escrevi a ANOS Atrás, mas de lá pra cá, muita coisa mudou ou ficou obsoleta.
Segue um código atualizado e funcional:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package com.ederbaum.io.pdf;
import com.ederbaum.io.IOUtil;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorker;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.parser.XMLParser;
import com.itextpdf.tool.xml.pipeline.css.CSSResolver;
import com.itextpdf.tool.xml.pipeline.css.CssResolverPipeline;
import com.itextpdf.tool.xml.pipeline.end.PdfWriterPipeline;
import com.itextpdf.tool.xml.pipeline.html.AbstractImageProvider;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipeline;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.itextpdf.text.pdf.codec.Base64;
import com.itextpdf.tool.xml.exceptions.CssResolverException;
import com.itextpdf.tool.xml.pipeline.html.ImageProvider;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
/**
*
* @author Éder
*/
public class Html2Pdf {
private final InputStream is;
private ImageProvider imProvider;
private CSSResolver cssResolver;
public Html2Pdf(InputStream is) throws TransformerConfigurationException, TransformerException {
this.is = is;
cssResolver = XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
this.imProvider = new Base64ImageProvider();
}
public Html2Pdf(String html) throws TransformerException {
this(new ByteArrayInputStream(html.getBytes()));
}
public void setImageProvider(ImageProvider imProvider) {
this.imProvider = imProvider;
}
public void addCss(String css) throws CssResolverException {
cssResolver.addCss(css, Boolean.TRUE);
}
public void convert(OutputStream file) throws DocumentException, IOException {
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, file);
// step 3
document.open();
// step 4
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
if (imProvider != null) {
htmlContext.setImageProvider(imProvider);
}
// Pipelines
PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(is);
// step 5
document.close();
}
public void convert(File os) throws FileNotFoundException, IOException, DocumentException {
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(os))) {
convert(out);
}
}
public static void main(String[] args) throws IOException, FileNotFoundException, DocumentException, TransformerException, CssResolverException {
//Html2Pdf pdf = new Html2Pdf(new File("C:/tmp/private/boleto_tmp.html"));
Html2Pdf pdf = new Html2Pdf("<h1 style=\"color:red\">Tchau Querida</h1>");
pdf.setImageProvider(new Base64ImageProvider());
pdf.convert(new File("/out.pdf"));
}
static class Base64ImageProvider extends AbstractImageProvider {
@Override
public Image retrieve(String src) {
int pos = src.indexOf("base64,");
try {
if (src.startsWith("data") && pos > 0) {
byte[] img = Base64.decode(src.substring(pos + 7));
return Image.getInstance(img);
} else {
return Image.getInstance(src);
}
} catch (BadElementException | IOException ex) {
return null;
}
}
@Override
public String getImageRootPath() {
return null;
}
}
}
GOSTEI 1
Mais Respostas
Guilherme Zanetta
09/04/2009
Eu utilizei este código dentro de uma classe que eu preciso, mas quando vou executar, da um erro dizendo que não existe uma função dentro do iText.
Bom, fui pesquisar e vi que o iText mudou a assinatura do método e não manteve uma assinatura compatível afim de manter compatibilidade para versões anteriores.
Gostaria de saber qual foram as versões dos pacotes jars que estas utilizando?
Grato
GOSTEI 0
Paulo Santos
09/04/2009
Cara e se eu tenho uma imagem no HTML?
uma tag:
Como proceder?
<img src="sourceImage" />
GOSTEI 0
Paulo Santos
09/04/2009
E como setar o chaset?
GOSTEI 0
Paulo Santos
09/04/2009
E antes que me esqueça parabens pela solução, aqui funcionou, execto as imagens e o charset que eu to testando com Tidy tidy.setCharEconding(int charset);
GOSTEI 0
Faiter
09/04/2009
O problema que eu tive com as imagens que não apareciam no PDF, foram resolvidas modificando o caminho das imagens antes de passar para o componente que gera o PDF.
No meu caso:
../imagens/imagem.jpg
Para:
Contexto/imagens/imagem.jpg
Grande abraço a todos.
GOSTEI 0
Ederbaum
09/04/2009
zanetta
Os jars quue funcionan disponibilzei aqui: http://dl.getdropbox.com/u/15403/Html2PDF.zip
GOSTEI 0
Diego Pagliosa
09/04/2009
Opa, e quanto a estilização em css do PDF??
no caso eu programo em PHP e existe uma classe que renderiza o HTML e o CSS junto, estilizando como se fosse um página normal de qualquer site.
Nessa método, ele estiliza o HTML de acordo com o css ou não?
GOSTEI 0
Carlos Fonseca
09/04/2009
[quote="diegoalpa"]Opa, e quanto a estilização em css do PDF??
no caso eu programo em PHP e existe uma classe que renderiza o HTML e o CSS junto, estilizando como se fosse um página normal de qualquer site.
Nessa método, ele estiliza o HTML de acordo com o css ou não?
Esquece o itext, a licença dele é AGPL, a menos que você esteja usando para um projeto open source !, fora isso vai precisar comprar uma licença!
Pessoal tem que verificar esse tipo de coisa antes de falar que a lib é livre, pois não é!
GOSTEI 0
Diego Pagliosa
09/04/2009
Sei que já um tanto velho o posto...
mas tenho algumas tabelas no html e quando renderiza o conteúdo para pdf as tabelas são cortadas... teria alguma forma bacana de evitar isso?
o conteúdo das tabelas são dinâmicas...
GOSTEI 0
Guilherme Goll
09/04/2009
Opa, você conseguiu encontrar uma solução para este caso Giuliano? Estou com o mesmo problema de algumas tabelas sendo cortadas quando renderizo o html.
GOSTEI 0
Guilherme Goll
09/04/2009
Bom dia!
Alguem poderia me tirar uma duvida a respeito desse post:
Nao estou conseguindo passar o nome do arquivo que preciso transformar para PDF, pois ele esta entendendo que o nome do arquivo e para conveter
GOSTEI 0