Last active
June 28, 2021 05:25
-
-
Save kylefelipe/26cd5b8c883b1d4b446551e8ad63995a to your computer and use it in GitHub Desktop.
Script python para gerar vários documentos usando um DOCX como template e uma planilha XLSX como base de dados
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
################################################################################## | |
# Script python para gerar vários documentos usando um DOCX como template | |
# e uma planilha XLSX como base de dados. | |
# é necessário ter um template preparado antes. | |
# | |
# Autor: Kyle Felipe Vieira Roberto | |
# Data de Criação: quarta-feira 19 de julho de 2017 | |
# | |
################################################################################## | |
from docx import Document | |
from docx import table | |
from openpyxl import load_workbook | |
import re | |
# Códigos de auxílio | |
remover = "[-,./()]" # Remover caracteres | |
# Trabalhando os dados do EXCEL | |
# Abrindo o arquivo excel com a base de dados | |
caderno = load_workbook(filename='NOTIFICAR_TESTE.xlsx') | |
folhas = caderno['notificar'] # Escolhendo a aba com a base de dados | |
# Criando lista com CNPJs únicos | |
cnpj_unicos = set() # set pega apenas os dados únicos dos cnpjs | |
for linha in folhas.iter_rows('B{}:B{}' .format(folhas.min_row + 1, folhas.max_row)): | |
for celula in linha: | |
cnpj_unicos.add(celula.value) | |
lista_cnpj = list(cnpj_unicos) # Transformando o set em lista | |
# Dicionario com os nomes das empresas | |
cnpj_nome = {} # Chave referente aos dados dos cnpj | |
# Define a area de CNPJ e nomes | |
cnpj_nome_cel = folhas.iter_rows(('B{}:C{}' .format((folhas.min_row + 1), (folhas.max_row)))) | |
# Popula o Dicionário cnpj_nome com os dados | |
for celula_1, celula_2 in cnpj_nome_cel: | |
cnpj_nome.update([('{}' .format(celula_1.value), '{}' .format(celula_2.value))]) | |
total = len(cnpj_nome) # Pega o total de CNPJ de empresas a serem notificadas | |
# Solicitando alguns dados para as notificações | |
print('Quantidade de notificações: {}' .format(total)) | |
data_notificação = input("Digite a data de notificação com o mês por extenso: ") | |
Notificacao_inicial = int(input('Qual a primeira notificação: ')) #Pega o número da primeira notificação | |
# Criando as notificações | |
for i in range(total): | |
documento = Document('NOTIFICA_Mala_direta.docx') # Abrindo o DOCX base da notificacao | |
cnpj = lista_cnpj[i] | |
cnp_limpo = (''.join(c for c in cnpj if c.isdigit())) # Limpa os caracteres especiais do CNPJ | |
nome_limpo = re.sub(remover, '', cnpj_nome[cnpj]) # Limpa os caracteres especiais do CNPJ retirar | |
num_notificacao = Notificacao_inicial + i # Cria o número da notificação | |
# cria uma lista com os paragrafos do texto, parágrafos necessários são 0, 3, 5, 6 | |
para = list(documento.paragraphs) | |
# Modifica o texto do paragrafo 0 - numero da notificação | |
numnot_s = para[0].text | |
para[0].text = numnot_s.format(num_notificacao) | |
# Modifica o texto do parágrafo 3 - Data | |
empresa_s = para[3].text | |
para[3].text = empresa_s.format(data_notificação) | |
# Modifica o texto do parágrafo 5 - Empresa | |
empresa_s = para[5].text | |
para[5].text = empresa_s.format(re.sub(remover, '', cnpj_nome[cnpj])) | |
# Modifica o texto do parágrafo 6 - CNPJ | |
empresa_s = para[6].text | |
para[6].text = empresa_s.format(cnpj) | |
# Trabalhando os dados do EXCEL | |
dados_planilha = [] # Armazena os dados da empresa | |
# Define a área da planilha principal a ser usada | |
colunas_dados = folhas.iter_rows( | |
('B{}:J{}'.format((folhas.min_row + 1), (folhas.max_row)))) # Define a área dos valores da notificação | |
# Populando a lista aninhada com os dados da empresa (cnpj) | |
for cnpj_emp, empresa, codigo, produto, volume, medida, periodo, mes, ano in colunas_dados: | |
if cnpj_emp.value == cnpj: | |
dados_planilha.append([produto.value, volume.value, medida.value, mes.value, ano.value]) | |
# Trabalhando a tabela da notificação | |
tabelas_d = list(documento.tables) # Pega a tabela criada dentro do documento padrão (template) | |
tabela_d = tabelas_d[0] | |
linhas_d = tabela_d.rows | |
cabeca_d = tabela_d.rows[0].cells # cabeçalho da tabela | |
# Polulando a tabela do documento | |
for item_d in dados_planilha: | |
adiciona = tabela_d.add_row().cells | |
adiciona[0].text = str(item_d[0]) | |
adiciona[1].text = str(item_d[1]) | |
adiciona[2].text = str(item_d[2]) | |
adiciona[3].text = str(item_d[3]) | |
adiciona[4].text = str(item_d[4]) | |
# Mudando a formatação de cada célula da tabela do documento | |
for linha_d in tabela_d.rows: | |
for celula_d in linha_d.cells: | |
celula_d.paragraphs[0].style = documento.styles['Normal2'] # Pode criar um estilo dentro do documento | |
# do remplate q ser aplicado à célula da tabela | |
documento.save('NOTIFICAÇÃO nº {0} - {1}.docx'.format(num_notificacao, | |
nome_limpo)) # Salvando o arquivo |
@isouzasoares eu tentei usar fora do for, o problema é que na primeira iteração a variável {} era trocada e o texto do documento ficava o mesmo em todas as notificações... quando eu coloquei dentro funcionou do modo que eu queria
Boa @FelipeSBarros, não tinha pensado nisso...
Eu criei um campo de mala direta chamado , mas não está substituindo. O que pode ser?
Eu criei um campo de mala direta chamado , mas não está substituindo. O que pode ser?
@damiaorocha
Raapz.. faz tanto tempo que fiz esse script....
Tem de ver o erro que está dando..
Se não me engano, quando fiz esse script. ele rodava em python 2
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Na linha 27 e 28 o file name
'NOTIFICAR_TESTE.xlsx'
podería ser solicitado ao usuário, permitindo que a função seja utilizável idenpendente do nome do.xlsx
.Mas isso é só um ponto para que seja reproduzível de forma mais "livre"....
Good job!