Unificar la extensión
Hay ocasiones en las que nos interesa unificar el tipo de documentos a fin de simplificar procesos posteriores. En estos casos disponer de un procedimiento que transforma todos los arhcivos a un mismo tipo es una buena solución.
Cuando la procedencia de los archivos es diversa suele suceder que acabamos trbajando con documentos de contenido similar (o igual) pero en diferentes formatos. Un ejemplo de ello son los archivos derivados del uso de procesadores de texto en los que incluso usando el mismo servicio (MSO-Word) podemos generar documentos .doc o documentos .docx. Si a esto añadimos el uso de LO-Writer obtendremos una colección de archivos en tres formatos diferentes: .doc, .docx y .odt. Cierto que LO-Writer permite acceder a todos ellos indistintamente y de forma fiable y segura, pero si queremos automatizar determinados procesos desde Python unificar la tipología de los archivos puede considerarse una media previa cuanto menos conveniente.
El script que sigue permite unificar todos los archivos de una ruta al formato .docx, lo que facilita el posterior tratamiento de todos los archivos con las funciones disponibles en la biblioteca python-docx.
#Bibliotecas necesarias ---------------------------------------------------
import os
import subprocess
import pathlib
#Función -------------------------------------------------------------------
def convertir_y_limpiar(ruta_absoluta):
# Configuración de ruta
RUTA_LIBREOFFICE = r'C:\Program Files\LibreOffice\program\soffice.exe'
if not os.path.exists(RUTA_LIBREOFFICE):
print(f"Error: No se encontró LibreOffice en {RUTA_LIBREOFFICE}")
return
extensiones_a_convertir = {'.doc', '.odt'}
if not os.path.exists(ruta_absoluta):
print(f"Error: La ruta {ruta_absoluta} no existe.")
return
print(f"Procesando archivos en: {ruta_absoluta}...\n")
for raiz, dirs, archivos in os.walk(ruta_absoluta):
for nombre_archivo in archivos:
ruta_original = pathlib.Path(os.path.join(raiz, nombre_archivo))
ext = ruta_original.suffix.lower()
# 1. Ignorar si ya es .docx
if ext == '.docx':
continue
# 2. Procesar solo .doc y .odt
if ext in extensiones_a_convertir:
# Definimos cómo se llamaría el nuevo archivo
ruta_nuevo_docx = ruta_original.with_suffix('.docx')
print(f"Transformando: {nombre_archivo} -> {ruta_nuevo_docx.name}")
try:
# Ejecutar conversión
resultado = subprocess.run([
RUTA_LIBREOFFICE,
'--headless',
'--convert-to', 'docx',
'--outdir', str(ruta_original.parent),
str(ruta_original)
], check=True, capture_output=True)
# 3. Verificación de seguridad: ¿Existe el nuevo archivo?
if ruta_nuevo_docx.exists():
# Eliminamos el original solo si el nuevo ya existe
os.remove(ruta_original)
print(f" [OK] Convertido y eliminado original.")
else:
print(f" [!] Error: No se encontró el archivo convertido {ruta_nuevo_docx.name}")
except Exception as e:
print(f" [X] Error procesando {nombre_archivo}: {e}")
print("\n¡Limpieza y conversión completadas!")
#Script de aplicación de función ---------------------------------------------------------------------
if __name__ == "__main__":
mi_ruta = "Mi_Ruta"
convertir_y_limpiar(mi_ruta)
Este script convierte archivos de tipo extensiones_a_convertir = {'.doc', '.odt'} a archivos .docx usando LO RUTA_LIBREOFFICE = r'C:\Program Files\LibreOffice\program\soffice.exe'. No es la única opción, pero sí muy recomendable (y gratuita), motivo por el que insisto en el interés que tiene trabajar con LibreOffice también para automatizar procesos con Python.
En este caso el script susituye los archivos originales por los convertidos, por lo que deberás hacer una copia de seguirdad de aquellos si los quieres. Este otro script mantiene los archivos originales y genera un nuevo directorio donde archiva los convertidos
#---Bibliotecas necesarias ------------------------------------------------
import os
import subprocess
import pathlib
#---Función de conversión -------------------------------------------------
def convertir_a_nueva_carpeta(ruta_origen, carpeta_destino):
# 1. Configuración de rutas
RUTA_LIBREOFFICE = r'C:\Program Files\LibreOffice\program\soffice.exe'
if not os.path.exists(RUTA_LIBREOFFICE):
print(f"Error: No se encontró LibreOffice.")
return
# 2. Crear la carpeta de destino si no existe
ruta_destino_abs = pathlib.Path(carpeta_destino).resolve()
if not ruta_destino_abs.exists():
os.makedirs(ruta_destino_abs)
print(f"Carpeta creada: {ruta_destino_abs}")
extensiones_a_convertir = {'.doc', '.odt'}
print(f"Leyendo de: {ruta_origen}")
print(f"Guardando en: {ruta_destino_abs}\n")
for raiz, dirs, archivos in os.walk(ruta_origen):
for nombre_archivo in archivos:
ruta_original = pathlib.Path(os.path.join(raiz, nombre_archivo))
ext = ruta_original.suffix.lower()
if ext in extensiones_a_convertir:
print(f"Convertiendo: {nombre_archivo}...")
try:
# 3. Ejecutar conversión apuntando al NUEVO directorio
subprocess.run([
RUTA_LIBREOFFICE,
'--headless',
'--convert-to', 'docx',
'--outdir', str(ruta_destino_abs), # <--- AQUÍ está el cambio clave
str(ruta_original)
], check=True, capture_output=True)
# 4. Verificación (Opcional, pero recomendada)
nuevo_archivo = ruta_destino_abs / (ruta_original.stem + ".docx")
if nuevo_archivo.exists():
print(f" [OK] Guardado en destino.")
except Exception as e:
print(f" [X] Error con {nombre_archivo}: {e}")
print("\n¡Proceso finalizado! Los archivos originales permanecen intactos.")
# --- Llamada a la función ------------------------------------------------------------
if __name__ == "__main__":
origen = "Mi_Ruta_Documentos" # Carpeta donde están tus .doc/.odt
destino = "Documentos_Convertidos" # Nueva carpeta donde se guardarán
convertir_a_nueva_carpeta(origen, destino)
La conversión a .docx no es la única posible, y en muchos casos tampoco la más adecuada, siendo .pdf la extensión preferida para realizar determinadas transaciones o el almacenamiento de documentos. Además también disponemos de biblitecas Python para trabajar con estos documentos. Por ello te proporciono un tercer y último script que convierte archivos procedentes de los servicios de procesador de texto a .pdf tomando a LibreOffice como tecnología de base.
#---Bibliotecas necesarias ------------------------------------------------
import os
import subprocess
import pathlib
#---Función de conversión -------------------------------------------------
def generar_pdfs_en_destino(ruta_origen, carpeta_pdf):
# --- Configuración ---
RUTA_LIBREOFFICE = r'C:\Program Files\LibreOffice\program\soffice.exe'
if not os.path.exists(RUTA_LIBREOFFICE):
print(f"Error: LibreOffice no detectado en {RUTA_LIBREOFFICE}")
return
# Extensiones que queremos convertir a PDF
extensiones_admitidas = {'.doc', '.docx', '.odt'}
# Crear carpeta de destino absoluta
ruta_salida = pathlib.Path(carpeta_pdf).resolve()
if not ruta_salida.exists():
os.makedirs(ruta_salida)
print(f"Carpeta de salida creada: {ruta_salida}")
print(f"Iniciando conversión de documentos a PDF...")
print(f"Origen: {ruta_origen}\n" + "-"*30)
# --- Procesamiento ---
for raiz, dirs, archivos in os.walk(ruta_origen):
for nombre_archivo in archivos:
ruta_archivo_original = pathlib.Path(os.path.join(raiz, nombre_archivo))
ext = ruta_archivo_original.suffix.lower()
if ext in extensiones_admitidas:
print(f"Procesando: {nombre_archivo}...")
try:
# Ejecutar LibreOffice para exportar a PDF
subprocess.run([
RUTA_LIBREOFFICE,
'--headless',
'--convert-to', 'pdf',
'--outdir', str(ruta_salida),
str(ruta_archivo_original)
], check=True, capture_output=True)
# Verificación de que el PDF se creó
nombre_esperado = ruta_archivo_original.stem + ".pdf"
if (ruta_salida / nombre_esperado).exists():
print(f" [OK] PDF generado correctamente.")
else:
print(f" [!] Advertencia: No se confirmó la creación de {nombre_esperado}")
except Exception as e:
print(f" [X] Error al convertir {nombre_archivo}: {e}")
print("\n" + "-"*30 + "\n¡Proceso completado! Los archivos originales no han sido modificados.")
# --- Ejecución den la función -----------------------------------------------------------------------
if __name__ == "__main__":
# Define tus rutas aquí
mi_directorio_original = "Documentos_Trabajo"
mi_directorio_pdfs = "Archivo_Exportado_PDF"
generar_pdfs_en_destino(mi_directorio_original, mi_directorio_pdfs)