0
When I create a pdf document from an html, there is a problem regarding accented characters and italic "Ç". When I open the document, strange characters appear instead of the original ones. How to proceed to solve this problem?
public void criaDocumento(DocumentoFiltro filtro, ModeloDocumento modelo, Empresa empresa, String erro) {
int idx = 0;
ModeloDocumentoItem itemOriginal;
String templateModelo = new String(modelo.getTemplate());
Documento documento = null;
DocumentoService documentoService = DocumentoService.getInstance();
DocumentoProcessoService documentoProcessoService = DocumentoProcessoService.getInstance();
DocumentoVersaoService documentoVersaoService = DocumentoVersaoService.getInstance();
try {
// Varre os itens preenchidos do modelo
for (ModeloDocumentoItem item : filtro.getModeloDocumento().getListaModeloDocumentoItem()) {
// Como os itens preenchidos estão ordenardos conforme a ordem definida no cadastro,
// para pegar o item original (cadastrado no banco), basta seguir o índice normal
// (Isso só é possível pois ao carregar do banco o modelo, seus itens ja vem ordernardos)
itemOriginal = modelo.getListaModeloDocumentoItem().get(idx++);
switch (itemOriginal.getTipo()) {
case CHECKBOX:
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), Boolean.TRUE.equals(item.getRespostaCheckbox()) ? "Sim" : "Não");
break;
case SELECT:
// Se o item é obrigatório e não está preenchido, retorna mensagem de erro
if (Boolean.TRUE.equals(itemOriginal.getObrigatorio()) && item.getRespostaSelect() == null) {
erro = "Não foi possível criar o documento. Todos os itens obrigatórios devem ser preenchidos.";
return;
}
if (item.getRespostaSelect() != null) {
String[] valores = itemOriginal.getValoresPossiveis().split(";");
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), Matcher.quoteReplacement(valores[item.getRespostaSelect()]));
} else {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), "");
}
break;
case TEXTO:
// Se o item é obrigatório e não está preenchido, retorna mensagem de erro
if (Boolean.TRUE.equals(itemOriginal.getObrigatorio()) && (item.getRespostaTexto() == null || "".equals(item.getRespostaTexto().trim()))) {
erro = "Não foi possível criar o documento. Todos os itens obrigatórios devem ser preenchidos.";
return;
}
if (item.getRespostaTexto() != null && !"".equals(item.getRespostaTexto())) {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), Matcher.quoteReplacement(item.getRespostaTexto()));
} else {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), "");
}
break;
case TEXTO_LONGO:
// Se o item é obrigatório e não está preenchido, retorna mensagem de erro
if (Boolean.TRUE.equals(itemOriginal.getObrigatorio()) && (item.getRespostaTexto() == null || "".equals(item.getRespostaTexto().trim()))) {
erro = "Não foi possível criar o documento. Todos os itens obrigatórios devem ser preenchidos.";
return;
}
if (item.getRespostaTexto() != null && !"".equals(item.getRespostaTexto())) {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), Matcher.quoteReplacement(item.getRespostaTexto()));
} else {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), "");
}
break;
case NUMERICO:
// Se o item é obrigatório e não está preenchido, retorna mensagem de erro
if (Boolean.TRUE.equals(itemOriginal.getObrigatorio()) && item.getRespostaNumero() == null) {
erro = "Não foi possível criar o documento. Todos os itens obrigatórios devem ser preenchidos.";
return;
}
if (item.getRespostaNumero() != null) {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), Matcher.quoteReplacement(NumberFormat.getNumberInstance(new Locale("pt","BR")).format(item.getRespostaNumero())));
} else {
templateModelo = templateModelo.replaceAll(Pattern.quote(itemOriginal.getNomeTermo()), "");
}
break;
default:
break;
}
}
HttpServletRequest request = NeoWeb.getRequestContext().getServletRequest();
ServletContext servletContext = ((WebApplicationContext) Neo.getApplicationContext()).getServletContext();
StringBuilder template = new StringBuilder();
// Carrega os estilos utilizados pelo plugin do editor de texto
String cssEditor = IOUtils.toString(servletContext.getResourceAsStream("/css/estilo_conversor_pdf.css"), "UTF-8");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter writer = new PdfWriter(baos);
PdfDocument pdfDocument = new PdfDocument(writer);
// Se o usuário não informou o tamanho das margens, seta-se um tamanho padrão (em centímetros)
if (modelo.getMargemSuperior() == null)
modelo.setMargemSuperior(2.5);
if (modelo.getMargemInferior() == null)
modelo.setMargemInferior(2.5);
if (modelo.getMargemEsquerda() == null)
modelo.setMargemEsquerda(3.0);
if (modelo.getMargemDireita() == null)
modelo.setMargemDireita(3.0);
// Se o usuário adicionou uma imagem de cabeçalho
if (modelo.getNomeImagemCabecalho() != null) {
Image imagem = null;
String bucketName = AwsUtil.BUCKET_NAME;
String key = Normalizer.normalize(request.getServerName() + "/modelos/cabecalhos/" + modelo.getId() + "." + FilenameUtils.getExtension(modelo.getNomeImagemCabecalho()).toLowerCase(), Normalizer.Form.NFC);
try {
// Busca a imagem no repositório do s3
byte[] arquivoImagem = IOUtils.toByteArray(AwsUtil.getObject(bucketName, key));
imagem = new Image(ImageDataFactory.create(arquivoImagem));
// Cria o evento que adiciona o cabeçalho
// O evento é acionado no início da renderização de cada página
Header headerHandler = new Header(imagem, modelo);
pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, headerHandler);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
// Se o usuário adicionou uma imagem de rodapé
if (modelo.getNomeImagemRodape() != null) {
Image imagem = null;
String bucketName = AwsUtil.BUCKET_NAME;
String key = Normalizer.normalize(request.getServerName() + "/modelos/rodapes/" + modelo.getId() + "." + FilenameUtils.getExtension(modelo.getNomeImagemRodape()).toLowerCase(), Normalizer.Form.NFC);
try {
// Busca a imagem no repositório do s3
byte[] arquivoImagem = IOUtils.toByteArray(AwsUtil.getObject(bucketName, key));
imagem = new Image(ImageDataFactory.create(arquivoImagem));
// Cria o evento que adiciona o rodapé
// O evento é acionado no fim da renderização de cada página
Footer footerHandler = new Footer(imagem, modelo);
pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, footerHandler);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
// Se o usuário marcou para inserir numeração de página
if (Boolean.TRUE.equals(modelo.getInserirNumeracaoPagina())) {
NumberPage numberPageHandler = new NumberPage();
pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, numberPageHandler);
}
// Adiciona na string de estilos um estilo que adiciona as margens das páginas
String cssMargens = "@page {margin: ";
cssMargens += Double.toString(modelo.getMargemSuperior() * 37.795275591) + "px ";
cssMargens += Double.toString(modelo.getMargemDireita() * 37.795275591) + "px ";
cssMargens += Double.toString(modelo.getMargemInferior() * 37.795275591) + "px ";
cssMargens += Double.toString(modelo.getMargemEsquerda() * 37.795275591) + "px;}";
cssEditor += cssMargens;
template.append("<html><head><style>");
// Adiciona os estilos no head para gerar o pdf com a formatação correta
// (O editor adiciona tags com classes para gerar a formatação, onde os estilos são aplicados as classes)
template.append(cssEditor);
template.append("</style></head><body>");
// Adiciona uma tag com a classe ql-editor (tag criada pelo editor) para os estilos serem aplicados corretamente ao template
template.append("<div id=\"editor\">");
template.append(templateModelo);
template.append("</div>");
template.append("</body></html>");
ConverterProperties converterProperties = new ConverterProperties();
FontProvider dfp = new DefaultFontProvider(true, true, false);
// Adiciona fontes específicas utilizadas no editor para o iText reconhecê-las no momento da geração do pdf
// Fontes Arial
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/arial.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/arialbd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/arialbi.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/ariali.ttf")));
// Fontes Comic Sans
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/comic.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/comicbd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/comici.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/comicz.ttf")));
// Fontes Courier New
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/cour.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/courbd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/courbi.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/couri.ttf")));
// Fontes Helvetica Neue
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/helvetica-neue.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/helvetica-neuebd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/helvetica-neuebi.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/helvetica-neuei.ttf")));
// Fontes Garamond
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/garamond.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/garamondbd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/garamondit.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/garamondbi.ttf")));
// Fonte Impact
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/impact.ttf")));
// Fontes Tahoma
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/tahoma.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/tahomabd.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/tahomai.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/tahomabi.ttf")));
// Fontes Verdana
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/verdana.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/verdanab.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/verdanai.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/verdanaz.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/OpenSans-Bold.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/OpenSans-BoldItalic.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/OpenSans-Italic.ttf")));
dfp.addFont(IOUtils.toByteArray(servletContext.getResourceAsStream("/fonts/Arial-Italic.ttf")));
converterProperties.setFontProvider(dfp);
// Converte o html para pdf
HtmlConverter.convertToPdf(template.toString(), pdfDocument, converterProperties);
// Obtém os bytes do arquivo pdf gerado
byte[] bytesDocumento = baos.toByteArray();
documento = new Documento();
// Se o usuário preencheu o nome do documento no momento de preencher os itens do modelo, este será o nome
// Do contrário, considera que o nome do documento será o mesmo do modelo
if (filtro.getNome() != null && !"".equals(filtro.getNome().trim())) {
documento.setNome(filtro.getNome() + ".pdf");
} else {
documento.setNome(modelo.getNome() + ".pdf");
}
// Seta as informações do documento para salvar na base
documento.setDiretorio(filtro.getDiretorio());
documento.setExtensao("pdf");
documento.setTamanho(new Long(bytesDocumento.length));
documento.setDataEnvio(DateUtil.getDataAtualTimestamp());
documento.setUltimaAlteracao(documento.getDataEnvio());
documento.setResponsavel(filtro.getResponsavel());
documento.setTitulo(FilenameUtils.getBaseName(documento.getNome()));
documento.setAutor(filtro.getResponsavel().getNome());
documento.setDataDigitalizacao(documento.getDataEnvio());
documento.setResponsavelDigitalizacao(filtro.getResponsavel());
documento.setTipo(modelo.getTipo());
if (documentoService.contemDocumentoMesmoNome(documento, filtro.getDiretorio())) {
documento.setNome(documentoService.geraNovoNomeDocumentoIgual(documento, filtro.getDiretorio()));
}
documentoService.saveOrUpdate(documento);
if(Boolean.TRUE.equals(empresa.getEnvioInteligente())) {
DocumentoProcesso documentoProcesso = new DocumentoProcesso(documento);
documentoProcesso.setStatusDirecionamento(StatusProcessamentoEnum.NAO_SE_APLICA);
if(documento.getTipo()!=null) {
documentoProcesso.setStatus(StatusProcessamentoEnum.PROCESSADO);
}
documentoProcesso.getListaObservacaoDocumentoProcesso().add(new ObservacaoDocumentoProcesso("Aguardando processamento"));
documentoProcessoService.saveOrUpdate(documentoProcesso);
}
DocumentoVersao documentoVersao = new DocumentoVersao(documento);
documentoVersaoService.saveOrUpdate(documentoVersao);
documento.setDocumentoVersao(documentoVersao);
documentoService.updateVersao(documento, documentoVersao);
// Envia o documento para o s3
String key = request.getServerName().concat("/").concat(documento.getId().toString()).concat(".").concat(documento.getExtensao());
ObjectMetadata metadata = new ObjectMetadata();
PutObjectResult result = AwsUtil.putObject(AwsUtil.BUCKET_NAME, key, new ByteArrayInputStream(bytesDocumento), metadata);
// Atualiza a hash do documento com a hash gerada pelo s3
documentoService.updateHash(documento, result.getETag().replace("\"", ""));
// Atualiza o espaço utilizado pela empresa
EmpresaService empresaService = EmpresaService.getInstance();
empresaService.updateEspacoUtilizado(documentoService.getSumTamanhoDocumentos());
// Verifica se o espaço utilizado atingiu algum dos limites (80, 90 e 100%)
// Nesse caso, envia um e-mail para os usuários administradores do sistema notificando sobre o limite atingido
if (empresa.getLimiteEspaco() != null) {
Double porcentagem = (empresa.getEspacoUtilizado() * 100.0) / empresa.getLimiteEspaco();
if (porcentagem >= 80.0 && porcentagem < 90.0) {
if (!Boolean.TRUE.equals(empresa.getUtilizou80())) {
empresaService.updateFlagUtilizou80(true);
empresaService.enviaEmailNotificacaoArmazenamento(empresa, true, false, false);
}
} else if (porcentagem >= 90.0 && porcentagem < 100.0) {
if (!Boolean.TRUE.equals(empresa.getUtilizou90())) {
empresaService.updateFlagUtilizou90(true);
empresaService.enviaEmailNotificacaoArmazenamento(empresa, false, true, false);
}
} else if (porcentagem >= 100.0) {
if (!Boolean.TRUE.equals(empresa.getUtilizou100())) {
empresaService.updateFlagUtilizou100(true);
empresaService.enviaEmailNotificacaoArmazenamento(empresa, false, false, true);
}
} else {
empresaService.updateFlagUtilizou80(false);
empresaService.updateFlagUtilizou90(false);
empresaService.updateFlagUtilizou100(false);
}
}
// Registra na auditoria a criação do documento
AuditoriaService.getInstance().registraAuditoriaDocumento(documento, AcaoAuditoriaEnum.CRIAR, "Criado a partir do modelo " + modelo.getNome() + ". Destino: " + filtro.getDiretorio().getCaminho());
} catch (Exception e) {
// Em caso do lançamento de alguma exceção, caso o documento esteja preenchido, quer dizer que o mesmo foi salvo no banco
// Nesse caso remove-se o mesmo para não ficar 'lixo' na base
if (documento != null) {
documentoService.delete(documento);
}
erro = "Ocorreu um erro ao criar o documento. Por favor, tente novamente.";
e.printStackTrace();
}
}
could you format the source code for a better view? Here we use markdown.
– Danizavtz