Skip to content

C# / .NET-бібліотека для Office — швидкий старт

OfficeOxide — це .NET-прив’язка до Rust-бібліотеки office_oxide. Дає .NET-додаткам швидкий, ощадний на алокації парсинг, конвертацію та редагування DOCX / XLSX / PPTX / DOC / XLS / PPT — під капотом AOT-сумісний LibraryImport-P/Invoke.

Встановлення

dotnet add package OfficeOxide --version 0.1.0

Потрібен .NET 8 або .NET 10. NuGet-пакет постачає prebuild-нативки для win-x64, linux-x64, linux-arm64, osx-x64, osx-arm64 під runtimes/<rid>/native/. dotnet publish сам кладе потрібну поряд із бінарем.

Прочитати документ

using OfficeOxide;

using var doc = Document.Open("report.docx");
Console.WriteLine(doc.PlainText());

Базовий API

Document — read-only handle; диспозите (краще через using), щоб звільнити нативну пам’ять.

using OfficeOxide;

using var doc = Document.Open("file.xlsx");

Console.WriteLine(doc.Format);        // "xlsx"
Console.WriteLine(doc.PlainText());
Console.WriteLine(doc.ToMarkdown());
Console.WriteLine(doc.ToHtml());
Console.WriteLine(doc.ToIrJson());

doc.SaveAs("file.docx");              // цільовий формат — за розширенням

Async-обгортка для блокуючого IO:

using var doc = await Document.OpenAsync("huge.pptx", ct);

Відкрити з байтів (без temp-файлу):

byte[] data = File.ReadAllBytes("report.docx");
using var doc = Document.FromBytes(data, "docx");

format повинен бути "docx", "xlsx", "pptx", "doc", "xls" або "ppt".

Статичні хелпери для одноразових викликів:

string text = OfficeOxide.ExtractText("file.docx");
string md   = OfficeOxide.ToMarkdown("file.pptx");
string html = OfficeOxide.ToHtml("file.xlsx");

string? fmt = Document.DetectFormat("mystery.bin"); // null, якщо не підтримується
Console.WriteLine(Document.Version);                // "0.1.0"

Редагування

Редагування зберігає дослівно всі незмінені OPC-частини (зображення, діаграми, відносини) при збереженні. Лише DOCX, XLSX та PPTX.

using OfficeOxide;

using var ed = EditableDocument.Open("template.docx");
long n = ed.ReplaceText("{{name}}", "Alice");
Console.WriteLine($"{n} замін");
ed.Save("out.docx");

ReplaceText повертає кількість замін (для XLSX — 0; використовуйте SetCell).

Заміна тексту в DOCX / PPTX

using var ed = EditableDocument.Open("slides.pptx");
ed.ReplaceText("Q3", "Q4");
ed.ReplaceText("2024", "2025");

byte[] bytes = ed.SaveToBytes();
File.WriteAllBytes("slides_q4.pptx", bytes);

Запис клітинок XLSX (чотири перевантаження)

using var wb = EditableDocument.Open("budget.xlsx");

wb.SetCell(0u, "A1", "Total");        // string-перевантаження
wb.SetCell(0u, "B1", 42.5);           // double-перевантаження
wb.SetCell(0u, "C1", true);           // bool-перевантаження
wb.SetCellEmpty(0u, "D1");            // очистити клітинку

wb.Save("budget.xlsx");

sheetIndex нумерується з нуля; cellRef — стандартна нотація електронних таблиць (A1, AA12).

Формат-незалежний IR

ToIrJson() повертає JSON-рядок, що відповідає Rust-структурі DocumentIR:

using System.Text.Json;

using var doc = Document.Open("report.docx");
string json = doc.ToIrJson();

using var ir = JsonDocument.Parse(json);
foreach (var section in ir.RootElement.GetProperty("sections").EnumerateArray())
{
    if (section.TryGetProperty("title", out var t) && t.ValueKind != JsonValueKind.Null)
        Console.WriteLine(t.GetString());
}

Робота з байтами

using var http = new HttpClient();
byte[] data = await http.GetByteArrayAsync("https://example.com/file.docx");
using var doc = Document.FromBytes(data, "docx");
Console.WriteLine(doc.ToMarkdown());

Legacy-формати

using var legacy = Document.Open("old.xls");
legacy.SaveAs("modern.xlsx");

AOT / Trimming

Проєкт задає IsAotCompatible=true та IsTrimmable=true. Усі P/Invoke використовують LibraryImport-source generator, тож dotnet publish -c Release -p:PublishAot=true дає єдиний self-contained виконуваний файл.

Помилки

Збої кидають OfficeOxideException із типізованою властивістю Code:

try
{
    using var doc = Document.Open("missing.docx");
}
catch (OfficeOxideException ex)
{
    Console.WriteLine($"code={ex.Code} op={ex.Operation}");
}

Виклик методів на disposed-handle кидає ObjectDisposedException.

Код Ім’я Значення
0 Ok успіх
1 InvalidArg null / порожньо / неправильний рядок формату
2 Io помилка файлової системи
3 Parse пошкоджений документ
4 Extraction парсинг ОК, але рендер не вдався
5 Internal баг — заведіть issue
6 Unsupported розширення/функція не підтримується

Діагностика

Симптом Що робити
DllNotFoundException: office_oxide Нативна бібліотека не скопійована поруч із бінарем. Запускайте dotnet publish, а не голий dotnet build.
BadImageFormatException на Windows Розбіжність архітектури — викочуйте відповідну збірку win-x64 або win-arm64.
OfficeOxideException із кодом Unsupported для .doc Переконайтесь, що розширення в нижньому регістрі, або передавайте формат явно через FromBytes.
Після trimming бракує символів Додайте OfficeOxide до <TrimmerRootAssembly>.
macOS «неможливо відкрити, бо розробника не підтверджено» Виконайте xattr -d com.apple.quarantine /path/to/liboffice_oxide.dylib або підпишіть бандл.

Дивіться також