In der heutigen digitalen Welt sind wir oft mit einer Flut von Dokumenten konfrontiert – sei es für die Arbeit, das Studium oder private Projekte. Aber wie behält man den Überblick über Metadaten, Inhalte und Strukturen dieser Dateien? Hier kommt der Document Folder Analyzer ins Spiel – ein Python-Tool mit einer modernen PyQt6-GUI, das Ordner mit verschiedenen Dokumentformaten analysiert und die Ergebnisse übersichtlich in Excel-Dateien speichert. In diesem Beitrag erkläre ich, wofür du es brauchst, wie du es installierst und wie die Ergebnisse aussehen.
Wofür braucht man den Document Folder Analyzer?
Der Analyzer ist ein vielseitiges Werkzeug für alle, die schnell Informationen aus Dokumenten extrahieren möchten, ohne jede Datei manuell öffnen zu müssen. Hier sind einige Einsatzmöglichkeiten:
- Dokumentenmanagement: Finde heraus, wann Dateien erstellt oder geändert wurden, wer der Autor ist (bei PDFs) oder wie viele Seiten, Absätze oder Zellen sie enthalten.
- Archivierung: Erstelle eine Übersicht über einen Ordner mit gemischten Dateitypen – ideal für Projekte oder rechtliche Dokumentationen.
- Forensische Analyse: Überprüfe Metadaten und Inhalte, um z. B. die Herkunft von PDFs oder Änderungen nachzuvollziehen.
- Effizienzsteigerung: Automatisiere repetitive Aufgaben wie das Zählen von Bildern in PDFs oder Zeilen in Textdateien.
Das Tool unterstützt vier Formate:
- PDF: Seiten, Text, Bilder, Anmerkungen, Zeichnungen, Metadaten.
- Word (.docx): Text, Absätze, Dateisystem-Metadaten.
- Text (.txt): Text, Zeilenanzahl, Dateisystem-Metadaten.
- Excel (.xlsx): Tabellenblätter, Zellenanzahl, Dateisystem-Metadaten.
Wie installiert man den Document Folder Analyzer?
Die Installation ist unkompliziert, erfordert aber ein paar Python-Bibliotheken. Folge diesen Schritten:
1. Python installieren
Stelle sicher, dass Python (mindestens Version 3.7) auf deinem System installiert ist. Du kannst es von python.org herunterladen.
2. Bibliotheken installieren
Öffne ein Terminal (oder die Eingabeaufforderung) und führe diesen Befehl aus, um alle benötigten Bibliotheken zu installieren:
bash
pip install PyQt6 PyMuPDF openpyxl python-docx
- PyQt6: Für die grafische Benutzeroberfläche.
- PyMuPDF: Zum Lesen von PDFs.
- openpyxl: Zum Erstellen und Bearbeiten von Excel-Dateien.
- python-docx: Zum Verarbeiten von Word-Dateien.
3. Code speichern
Kopiere den vollständigen Code (siehe unten) in eine Datei, z. B. document_folder_analyzer.py.
4. Programm starten
Navigiere im Terminal zum Speicherort der Datei und starte das Programm:
bash
python document_folder_analyzer.py
Ein Fenster mit dem Titel „Document Folder Analyzer“ öffnet sich, und du kannst loslegen!
Wie funktioniert das Tool?
- Ordner auswählen: Klicke auf „Ordner auswählen“ und wähle einen Ordner mit PDFs, Word-, Text- oder Excel-Dateien.
- Analyse starten: Das Tool analysiert jede Datei im Hintergrund und zeigt den Fortschritt mit einem grünen Fortschrittsbalken an.
- Statusmeldungen: Während der Analyse siehst du Meldungen wie „Analysiere: dokument.pdf“. Am Ende gibt es eine Zusammenfassung.
- Ergebnisse speichern: Für jede analysierte Datei wird eine Excel-Datei mit der Endung _analyse.xlsx erstellt.
Die GUI ist modern und intuitiv: Ein großer Button zum Auswählen, ein Fortschrittsbalken und ein Statusfeld, das in Blau (laufend), Grün (erfolgreich) oder Rot (Fehler) leuchtet.
Wie sehen die Ausgaben und Resultate aus?
Die Ergebnisse variieren je nach Dateityp. Hier ein Überblick:
PDF-Analyse (z. B. dokument_analyse.xlsx)
Eine Tabelle mit einer Zeile pro Seite:
Dateiname:Seite | Erstellungsdatum | Änderungsdatum | Text (erste 500 Zeichen) | Anzahl der Bilder | Anzahl der Anmerkungen | Anzahl der Zeichnungen | Autor | Titel | Betreff | Producer | Creator | Erstellungsdatum Metadaten | Änderungsdatum Metadaten |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
dokument.pdf:1 | 15. März 2023, 12:34 | 16. März 2023, 09:12 | „Dies ist ein Test…“ | 2 | 1 | 0 | Max Mustermann | Test PDF | Testzweck | Adobe Acrobat | PyMuPDF | 15. März 2023, 12:34 | 16. März 2023, 09:12 |
Word-Analyse (z. B. brief_analyse.xlsx)
Eine einfache Tabelle:
Dateiname | Erstellungsdatum | Änderungsdatum | Text (erste 500 Zeichen) | Anzahl der Absätze |
---|---|---|---|---|
brief.docx | 10. Januar 2025, 08:15 | 11. Januar 2025, 14:30 | „Sehr geehrte Damen…“ | 5 |
Text-Analyse (z. B. notizen_analyse.xlsx)
Dateiname | Erstellungsdatum | Änderungsdatum | Text (erste 500 Zeichen) | Zeilenanzahl |
---|---|---|---|---|
notizen.txt | 05. Februar 2025, 09:00 | 06. Februar 2025, 10:00 | „Einkaufsliste: Milch…“ | 12 |
Excel-Analyse (z. B. tabelle_analyse.xlsx)
Dateiname | Erstellungsdatum | Änderungsdatum | Anzahl der Tabellenblätter | Gesamtzahl der Zellen |
---|---|---|---|---|
tabelle.xlsx | 01. März 2025, 15:20 | 02. März 2025, 11:45 | 3 | 150 |
Zusammenfassung in der GUI
Nach der Analyse eines Ordners mit z. B. drei Dateien könnte die Zusammenfassung so aussehen:
Analyse abgeschlossen!
Erfolgreich analysiert: C:/Dokumente/dokument_analyse.xlsx
Erfolgreich analysiert: C:/Dokumente/brief_analyse.xlsx
Fehler bei notizen.txt: Datei konnte nicht geöffnet werden
Fazit
Der Document Folder Analyzer ist ein praktisches Tool für alle, die schnell und automatisiert Einblicke in ihre Dokumente gewinnen möchten. Egal, ob du PDFs auf Metadaten prüfen, Word-Dokumente auf Absätze analysieren oder Excel-Dateien auf ihre Struktur untersuchen willst – dieses Programm macht es möglich. Mit der einfachen Installation und der übersichtlichen GUI steht deinem Dokumentenmanagement nichts mehr im Weg.
Der vollständige Code
Hier ist der Code, den du einfach kopieren und nutzen kannst:
python
import sys
import fitz # PyMuPDF
import os
from datetime import datetime
import openpyxl
from openpyxl.styles import Font
from docx import Document # Für .docx-Dateien
from PyQt6.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QPushButton,
QLabel, QFileDialog, QProgressBar)
from PyQt6.QtCore import Qt, QThread, pyqtSignal
from PyQt6.QtGui import QFont
# Funktion zum Parsen des Datums aus PDF-Metadaten
def parse_pdf_date(pdf_date):
if not pdf_date or pdf_date == "Nicht verfügbar":
return "Nicht verfügbar"
try:
date_str = pdf_date[2:16]
date_obj = datetime.strptime(date_str, '%Y%m%d%H%M%S')
return date_obj.strftime('%d. %B %Y, %H:%M:%S')
except (ValueError, IndexError):
return "Nicht verfügbar"
# Funktion zum Extrahieren von Dateimetadaten
def get_file_metadata(file_path):
created = datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%d. %B %Y, %H:%M:%S')
modified = datetime.fromtimestamp(os.path.getmtime(file_path)).strftime('%d. %B %Y, %H:%M:%S')
return created, modified
# Analyse-Funktionen für verschiedene Dateitypen
def analyze_pdf(file_path):
filename = os.path.basename(file_path)
pdf = fitz.open(file_path)
metadata = pdf.metadata
meta_fields = {"author": "Nicht verfügbar", "title": "Nicht verfügbar", "subject": "Nicht verfügbar",
"producer": "Nicht verfügbar", "creator": "Nicht verfügbar",
"creationDate": "Nicht verfügbar", "modDate": "Nicht verfügbar"}
meta_fields.update({k: v or "Nicht verfügbar" for k, v in metadata.items()})
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "PDF Analyse"
headers = ["Dateiname:Seite", "Erstellungsdatum", "Änderungsdatum", "Text (erste 500 Zeichen)",
"Anzahl der Bilder", "Anzahl der Anmerkungen", "Anzahl der Zeichnungen", "Autor",
"Titel", "Betreff", "Producer", "Creator", "Erstellungsdatum Metadaten", "Änderungsdatum Metadaten"]
for col, header in enumerate(headers, 1):
sheet.cell(row=1, column=col, value=header).font = Font(bold=True)
for page_num in range(pdf.page_count):
page = pdf.load_page(page_num)
text = page.get_text("text")[:500]
created = parse_pdf_date(meta_fields["creationDate"])
modified = parse_pdf_date(meta_fields["modDate"])
images = len(page.get_images(full=True))
annotations = len(list(page.annots() or []))
drawings = len(page.get_drawings() or [])
row = page_num + 2
sheet.cell(row=row, column=1, value=f"{filename}:{page_num + 1}")
sheet.cell(row=row, column=2, value=created)
sheet.cell(row=row, column=3, value=modified)
sheet.cell(row=row, column=4, value=text)
sheet.cell(row=row, column=5, value=images)
sheet.cell(row=row, column=6, value=annotations)
sheet.cell(row=row, column=7, value=drawings)
sheet.cell(row=row, column=8, value=meta_fields["author"])
sheet.cell(row=row, column=9, value=meta_fields["title"])
sheet.cell(row=row, column=10, value=meta_fields["subject"])
sheet.cell(row=row, column=11, value=meta_fields["producer"])
sheet.cell(row=row, column=12, value=meta_fields["creator"])
sheet.cell(row=row, column=13, value=created)
sheet.cell(row=row, column=14, value=modified)
output_file = file_path.replace(".pdf", "_analyse.xlsx")
workbook.save(output_file)
pdf.close()
return output_file
def analyze_docx(file_path):
filename = os.path.basename(file_path)
doc = Document(file_path)
created, modified = get_file_metadata(file_path)
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "DOCX Analyse"
headers = ["Dateiname", "Erstellungsdatum", "Änderungsdatum", "Text (erste 500 Zeichen)", "Anzahl der Absätze"]
for col, header in enumerate(headers, 1):
sheet.cell(row=1, column=col, value=header).font = Font(bold=True)
text = " ".join([para.text for para in doc.paragraphs if para.text])[:500]
sheet.cell(row=2, column=1, value=filename)
sheet.cell(row=2, column=2, value=created)
sheet.cell(row=2, column=3, value=modified)
sheet.cell(row=2, column=4, value=text)
sheet.cell(row=2, column=5, value=len(doc.paragraphs))
output_file = file_path.replace(".docx", "_analyse.xlsx")
workbook.save(output_file)
return output_file
def analyze_txt(file_path):
filename = os.path.basename(file_path)
created, modified = get_file_metadata(file_path)
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = "TXT Analyse"
headers = ["Dateiname", "Erstellungsdatum", "Änderungsdatum", "Text (erste 500 Zeichen)", "Zeilenanzahl"]
for col, header in enumerate(headers, 1):
sheet.cell(row=1, column=col, value=header).font = Font(bold=True)
with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
text = f.read()[:500]
lines = len(f.readlines())
sheet.cell(row=2, column=1, value=filename)
sheet.cell(row=2, column=2, value=created)
sheet.cell(row=2, column=3, value=modified)
sheet.cell(row=2, column=4, value=text)
sheet.cell(row=2, column=5, value=lines)
output_file = file_path.replace(".txt", "_analyse.xlsx")
workbook.save(output_file)
return output_file
def analyze_xlsx(file_path):
filename = os.path.basename(file_path)
created, modified = get_file_metadata(file_path)
workbook = openpyxl.load_workbook(file_path)
analysis_workbook = openpyxl.Workbook()
sheet = analysis_workbook.active
sheet.title = "XLSX Analyse"
headers = ["Dateiname", "Erstellungsdatum", "Änderungsdatum", "Anzahl der Tabellenblätter", "Gesamtzahl der Zellen"]
for col, header in enumerate(headers, 1):
sheet.cell(row=1, column=col, value=header).font = Font(bold=True)
total_cells = sum(sheet.max_row * sheet.max_column for sheet in workbook.worksheets)
sheet.cell(row=2, column=1, value=filename)
sheet.cell(row=2, column=2, value=created)
sheet.cell(row=2, column=3, value=modified)
sheet.cell(row=2, column=4, value=len(workbook.worksheets))
sheet.cell(row=2, column=5, value=total_cells)
output_file = file_path.replace(".xlsx", "_analyse.xlsx")
analysis_workbook.save(output_file)
return output_file
# Worker-Thread für die Ordner-Analyse
class FolderAnalyzer(QThread):
status_update = pyqtSignal(str, str) # Text, Farbe
progress_update = pyqtSignal(int) # Fortschritt in Prozent
def __init__(self, folder_path):
super().__init__()
self.folder_path = folder_path
def run(self):
supported_extensions = {'.pdf', '.docx', '.txt', '.xlsx'}
files = [f for f in os.listdir(self.folder_path) if os.path.splitext(f.lower())[1] in supported_extensions]
if not files:
self.status_update.emit("Keine unterstützten Dateien im Ordner gefunden.", "red")
return
total_files = len(files)
processed_files = 0
results = []
for file in files:
file_path = os.path.join(self.folder_path, file)
self.status_update.emit(f"Analysiere: {file}", "blue")
try:
if file.lower().endswith('.pdf'):
output_file = analyze_pdf(file_path)
elif file.lower().endswith('.docx'):
output_file = analyze_docx(file_path)
elif file.lower().endswith('.txt'):
output_file = analyze_txt(file_path)
elif file.lower().endswith('.xlsx'):
output_file = analyze_xlsx(file_path)
results.append(f"Erfolgreich analysiert: {output_file}")
except Exception as e:
results.append(f"Fehler bei {file}: {str(e)}")
processed_files += 1
self.progress_update.emit(int((processed_files / total_files) * 100))
summary = "\n".join(results)
self.status_update.emit(f"Analyse abgeschlossen!\n\n{summary}", "green")
# Hauptfenster der GUI
class DocumentFolderAnalyzerApp(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Document Folder Analyzer")
self.setGeometry(100, 100, 600, 400)
self.setFixedSize(600, 400)
main_widget = QWidget()
self.setCentralWidget(main_widget)
layout = QVBoxLayout(main_widget)
layout.setAlignment(Qt.AlignmentFlag.AlignCenter)
title_label = QLabel("Document Folder Analyzer")
title_label.setFont(QFont("Arial", 18, QFont.Weight.Bold))
title_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
layout.addWidget(title_label)
self.status_label = QLabel("Bitte wähle einen Ordner mit Dokumenten aus.")
self.status_label.setFont(QFont("Arial", 10))
self.status_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
self.status_label.setWordWrap(True)
layout.addWidget(self.status_label)
self.progress_bar = QProgressBar()
self.progress_bar.setMaximum(100)
self.progress_bar.setValue(0)
self.progress_bar.setTextVisible(True)
self.progress_bar.setStyleSheet("""
QProgressBar { border: 1px solid grey; border-radius: 5px; text-align: center; }
QProgressBar::chunk { background-color: #4CAF50; border-radius: 3px; }
""")
layout.addWidget(self.progress_bar)
self.select_button = QPushButton("Ordner auswählen")
self.select_button.setFont(QFont("Arial", 12))
self.select_button.setStyleSheet("""
QPushButton { background-color: #4CAF50; color: white; padding: 8px; border-radius: 5px; }
QPushButton:hover { background-color: #45a049; }
QPushButton:disabled { background-color: #cccccc; }
""")
self.select_button.clicked.connect(self.select_folder)
layout.addWidget(self.select_button)
exit_button = QPushButton("Beenden")
exit_button.setFont(QFont("Arial", 12))
exit_button.setStyleSheet("""
QPushButton { background-color: #f44336; color: white; padding: 8px; border-radius: 5px; }
QPushButton:hover { background-color: #da190b; }
""")
exit_button.clicked.connect(self.close)
layout.addWidget(exit_button)
def select_folder(self):
folder_path = QFileDialog.getExistingDirectory(self, "Ordner mit Dokumenten auswählen")
if folder_path:
self.status_label.setText("Analyse wird durchgeführt...")
self.status_label.setStyleSheet("color: blue;")
self.select_button.setEnabled(False)
self.progress_bar.setValue(0)
self.worker = FolderAnalyzer(folder_path)
self.worker.status_update.connect(self.update_status)
self.worker.progress_update.connect(self.update_progress)
self.worker.finished.connect(self.enable_button)
self.worker.start()
def update_status(self, message, color):
self.status_label.setText(message)
self.status_label.setStyleSheet(f"color: {color};")
def update_progress(self, value):
self.progress_bar.setValue(value)
def enable_button(self):
self.select_button.setEnabled(True)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = DocumentFolderAnalyzerApp()
window.show()
sys.exit(app.exec())
Schreibe einen Kommentar