Estou com um probleminha em python. Tenho um código que tem a função de substituir tags em documentos docx, no template original as tags seguem uma formatação padrão, quando o código é executado o texto que substitui as tags perde a formatação, dito isso encontrei uma solução, porém não foi 100% efetiva, a função esta realizando a formatação das tags mas não está respeitando a regra para deixar algumas delas em negrito, qual será o problema? Lembrando que essas tags podem se repetir em varias partes do template. Esse é o código: # -*- coding: utf-8 -*- import pyodbc from docx import Document from docx.shared import Pt from docx.oxml.ns import qn import os import time import logging # Configuração do logger log_file_path = 'TemplatesJuridico/log/script_log.log' logging.basicConfig( filename=log_file_path, level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # Função para substituir tags e aplicar formatação específica def substituir_em_runs(paragraph, tag, valor): tag_formatacao = { '<nr_contrato_cliente>': {'font_name': 'Calibri', 'font_size': 12, 'bold': True}, '<ano_corrente>': {'font_name': 'Calibri', 'font_size': 12, 'bold': True}, '<nome_cliente>': {'font_name': 'Calibri', 'font_size': 10, 'bold': True}, '<nome_parceiro>': {'font_name': 'Calibri', 'font_size': 10, 'bold': True}, '<nome_indice_reajuste>': {'font_name': 'Calibri', 'font_size': 10, 'bold': False}, '<nr_mes_reajuste>': {'font_name': 'Calibri', 'font_size': 10, 'bold': False}, } default_formatacao = {'font_name': 'Calibri', 'font_size': 10, 'bold': False} # Verifica se a tag está presente no parágrafo full_text = ''.join(run.text for run in paragraph.runs) if tag not in full_text: return # Substitui a tag pelo valor novo_texto = full_text.replace(tag, valor if valor else "") for run in paragraph.runs: run.text = "" # Determina a formatação correta para a tag formatacao = tag_formatacao.get(tag, default_formatacao) # Adiciona o novo texto no parágrafo com formatação new_run = paragraph.add_run(novo_texto) new_run.font.name = formatacao['font_name'] new_run.font.size = Pt(formatacao['font_size']) new_run.font.bold = formatacao['bold'] r = new_run._element r.rPr.rFonts.set(qn('w:eastAsia'), formatacao['font_name']) # Função principal para substituir tags no documento def substituir_tags(doc, tags_mapping): for paragraph in doc.paragraphs: for tag, valor in tags_mapping.items(): substituir_em_runs(paragraph, tag, valor) for table in doc.tables: for row in table.rows: for cell in row.cells: for paragraph in cell.paragraphs: for tag, valor in tags_mapping.items(): substituir_em_runs(paragraph, tag, valor) # Função para gerar o template def gerar_template(numcontrato, opcao): if hasattr(gerar_template, "execuuted"): logging.info(f"Processo para o contrato {numcontrato} ja foi executado.") return gerar_template.executed = True start_time = time.time() try: logging.debug("Tentando conectar ao banco de dados.") conn = pyodbc.connect(connection_string) cursor = conn.cursor() logging.info("Conexao com o banco de dados estabelecida com sucesso.") except pyodbc.Error as e: logging.error(f"Erro ao conectar ao banco de dados: {e}") return # Aqui esta a query que busca aas informações do banco try: logging.debug(f"Executando a query: {query} com o parametro {numcontrato}") cursor.execute(query, numcontrato) resultado = cursor.fetchone() logging.debug(f"Resultado da consulta: {resultado}") except pyodbc.Error as e: logging.error(f"Erro ao executar a query SQL: {e}") return if resultado: try: (nr_contrato_cliente, nome_cliente, nome_parceiro, valor_contrato, data_contrato, descricao_servico, cidade_cliente, cidade_parceiro, uf_cidade_cliente, uf_cidade_parceiro, cep_cliente, cnpj_cliente, cnpj_parceiro, ie_cliente, end_cliente, end_parceiro, nr_cliente, nr_parceiro, bairro_cliente, ano_corrente, nome_indice_reajuste, mes_reajuste, nr_mes_reajuste) = resultado except ValueError as e: logging.error(f"Erro ao desempacotar o resultado: {e}") return else: logging.warning(f'Nenhum dado encontrado para o contrato {numcontrato}.') return cursor.close() conn.close() logging.info(f"Conexao com o banco de dados encerrada para o contrato {numcontrato}.") # Definir o caminho do template e o nome do arquivo de saída # Evita sobreescrever o arquivo counter = 1 while os.path.exists(output_path): output_path = f"{base_output_path}_{counter}.docx" counter += 1 doc = Document(template_path) tags_mapping = { '<nr_contrato_cliente>': str(nr_contrato_cliente or ""), '<nome_cliente>': nome_cliente or "", '<nome_parceiro>': nome_parceiro or "", '<valor_contrato>': f"{valor_contrato:,.2f}" if valor_contrato is not None else "", '<data_contrato>': data_contrato or "", '<DESCRICAO_SERVICO>': descricao_servico or "", '<cidade_cliente>': cidade_cliente or "", '<cidade_parceiro>': cidade_parceiro or "", '<uf_cidade_cliente>': uf_cidade_cliente or "", '<uf_cidade_parceiro>': uf_cidade_parceiro or "", '<cep_cliente>': cep_cliente or "", '<cnpj_cliente>': cnpj_cliente or "", '<cnpj_parceiro>': cnpj_parceiro or "", '<ie_cliente>': ie_cliente or "", '<end_cliente>': end_cliente or "", '<end_parceiro>': end_parceiro or "", '<nr_cliente>': str(nr_cliente or ""), '<nr_parceiro>': str(nr_parceiro or ""), '<bairro_cliente>': bairro_cliente or "", '<ano_corrente>': str(ano_corrente or ""), '<nome_indice_reajuste>': nome_indice_reajuste or "", '<mes_reajuste>': mes_reajuste or "", '<nr_mes_reajuste>': nr_mes_reajuste or "" } substituir_tags(doc, tags_mapping) doc.save(output_path) logging.info(f"Template gerado com sucesso: {output_path}") end_time = time.time() elapsed_time = end_time - start_time logging.info(f"Template gerado com sucesso para o contrato {numcontrato}. Tempo total de execucao: {elapsed_time:.2f} segundos.") Desde já agradeço a ajuda. Eu tento formatar as tags conforme o código, mas não esta sendo 100% funcional, o problema está em deixar o texto substituído em negrito. Já fiz varias pesquisas e não encontrei a solução. Continue reading...