Jak parsować tabele w plikach OneNote przy użyciu Pythona

Jak parsować tabele w plikach OneNote przy użyciu Pythona

Microsoft OneNote pozwala użytkownikom osadzać tabele danych strukturalnych bezpośrednio na stronach. Aspose.Note FOSS for Python udostępnia każdą tabelę poprzez hierarchię Table → TableRow → TableCell, dając programowy dostęp do całej zawartości komórek, metadanych kolumn i znaczników tabeli.

Korzyści

  1. Strukturalny dostęp: liczba wierszy i kolumn, zawartość poszczególnych komórek, szerokości kolumn
  2. Nie wymaga aplikacji arkusza kalkulacyjnego: wyodrębnianie danych tabeli z OneNote na dowolnej platformie
  3. Darmowy i open-source: licencja MIT, brak klucza API

Przewodnik krok po kroku

Krok 1: Zainstaluj Aspose.Note FOSS dla Pythona

pip install aspose-note

Krok 2: Załaduj plik .one

from aspose.note import Document

doc = Document("MyNotes.one")
print(f"Pages: {len(list(doc))}")

Krok 3: Znajdź wszystkie tabele

Użyj GetChildNodes(Table), aby pobrać każdą tabelę z całego dokumentu rekurencyjnie:

from aspose.note import Document, Table

doc = Document("MyNotes.one")
tables = doc.GetChildNodes(Table)
print(f"Found {len(tables)} table(s)")

Krok 4: Odczyt wartości wiersza i komórki

Iteruj węzły TableRow i TableCell. Każda komórka zawiera węzły RichText, których właściwość .Text podaje treść w postaci zwykłego tekstu:

from aspose.note import Document, Table, TableRow, TableCell, RichText

doc = Document("MyNotes.one")

for t, table in enumerate(doc.GetChildNodes(Table), start=1):
    print(f"\nTable {t}: {len(table.Columns)} column(s)")
    for r, row in enumerate(table.GetChildNodes(TableRow), start=1):
        cell_values = []
        for cell in row.GetChildNodes(TableCell):
            text = " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip()
            cell_values.append(text)
        print(f"  Row {r}: {cell_values}")

Krok 5: Odczyt szerokości kolumn

from aspose.note import Document, Table

doc = Document("MyNotes.one")
for i, table in enumerate(doc.GetChildNodes(Table), start=1):
    print(f"Table {i} column widths (pts): {[col.Width for col in table.Columns]}")
    print(f"Borders visible: {table.IsBordersVisible}")

Krok 6: Eksport do CSV

import csv, io
from aspose.note import Document, Table, TableRow, TableCell, RichText

doc = Document("MyNotes.one")
buf = io.StringIO()
writer = csv.writer(buf)

for table in doc.GetChildNodes(Table):
    for row in table.GetChildNodes(TableRow):
        values = [
            " ".join(rt.Text for rt in cell.GetChildNodes(RichText)).strip()
            for cell in row.GetChildNodes(TableCell)
        ]
        writer.writerow(values)
    writer.writerow([])   # blank row between tables

with open("tables.csv", "w", encoding="utf-8", newline="") as f:
    f.write(buf.getvalue())
print("Saved tables.csv")

Typowe problemy i rozwiązania

Tabele wydają się puste

Cause: Komórki zawierają węzły Image zamiast węzłów RichText.

Sprawdź:

from aspose.note import Document, Table, TableRow, TableCell, RichText, Image

doc = Document("MyNotes.one")
for table in doc.GetChildNodes(Table):
    for row in table.GetChildNodes(TableRow):
        for cell in row.GetChildNodes(TableCell):
            texts = cell.GetChildNodes(RichText)
            images = cell.GetChildNodes(Image)
            print(f"  Cell: {len(texts)} text(s), {len(images)} image(s)")

Liczba kolumn nie pasuje Columns

table.Columns odzwierciedla metadane kolumn przechowywane w pliku. Rzeczywista liczba komórek w wierszu może się różnić, jeśli wiersze mają scalone komórki (format pliku przechowuje to na poziomie binarnym; publiczne API nie udostępnia flagi scalania).

ImportError: Brak modułu o nazwie ‘aspose’

pip install aspose-note
pip show aspose-note  # confirm it is installed in the active environment

Najczęściej zadawane pytania

Czy mogę edytować dane tabeli i zapisać je ponownie? Nie. Zapis z powrotem do formatu .one nie jest obsługiwany. Zmiany wprowadzone w pamięci (np. za pomocą RichText.Replace()) nie mogą być zachowane w pliku źródłowym.

Czy scalone komórki są wykrywane? API CompositeNode nie udostępnia metadanych scalania. Każdy TableCell jest traktowany jako oddzielna komórka, niezależnie od wizualnego scalania.

Czy mogę policzyć, ile wierszy ma tabela? Tak: len(table.GetChildNodes(TableRow)).


Powiązane zasoby:

 Polski