Skip to content

Biblioteca Office para C# / .NET — Início Rápido

OfficeOxide é o binding .NET para a biblioteca Rust office_oxide. Dá às aplicações .NET parsing, conversão e edição rápidos e econômicos em alocações para DOCX / XLSX / PPTX / DOC / XLS / PPT — por baixo, P/Invoke LibraryImport compatível com AOT.

Instalação

dotnet add package OfficeOxide --version 0.1.0

Requer .NET 8 ou .NET 10. O pacote NuGet entrega bibliotecas nativas pré-compiladas para win-x64, linux-x64, linux-arm64, osx-x64, osx-arm64 em runtimes/<rid>/native/. O dotnet publish coloca a correta ao lado do seu binário automaticamente.

Ler um documento

using OfficeOxide;

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

API principal

Document é o handle somente-leitura; faça dispose (de preferência via using) para liberar a memória nativa.

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");              // formato-alvo inferido pela extensão

Wrapper assíncrono para IO bloqueante:

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

Abrir a partir de bytes (sem arquivo temporário):

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

format precisa ser "docx", "xlsx", "pptx", "doc", "xls" ou "ppt".

Helpers estáticos para chamadas de uma vez:

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 se não suportado
Console.WriteLine(Document.Version);                // "0.1.0"

Edição

A edição preserva todas as partes OPC inalteradas (imagens, gráficos, relações) ao salvar. Apenas DOCX, XLSX e PPTX.

using OfficeOxide;

using var ed = EditableDocument.Open("template.docx");
long n = ed.ReplaceText("{{name}}", "Alice");
Console.WriteLine($"{n} substituições");
ed.Save("out.docx");

ReplaceText devolve a quantidade de substituições (0 em XLSX — use SetCell).

Substituir texto em 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);

Definir células XLSX (quatro overloads)

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

wb.SetCell(0u, "A1", "Total");        // overload string
wb.SetCell(0u, "B1", 42.5);           // overload double
wb.SetCell(0u, "C1", true);           // overload bool
wb.SetCellEmpty(0u, "D1");            // limpa a célula

wb.Save("budget.xlsx");

sheetIndex começa em zero; cellRef segue a notação padrão de planilhas (A1, AA12).

IR independente de formato

ToIrJson() devolve uma string JSON que segue a forma da DocumentIR em Rust:

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());
}

Pipelines em bytes

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());

Formatos legados

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

AOT / trimming

O projeto define IsAotCompatible=true e IsTrimmable=true. Todos os P/Invokes usam o gerador de fonte LibraryImport, então dotnet publish -c Release -p:PublishAot=true produz um único executável self-contained.

Erros

Falhas disparam OfficeOxideException com a propriedade tipada Code:

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

Chamar métodos em um handle já dispose-ado lança ObjectDisposedException.

Código Nome Significado
0 Ok sucesso
1 InvalidArg null / vazio / string de formato errada
2 Io erro de filesystem
3 Parse documento corrompido
4 Extraction parsing OK, mas o render falhou
5 Internal bug — abra uma issue
6 Unsupported extensão/feature não suportada

Solução de problemas

Sintoma Solução
DllNotFoundException: office_oxide A biblioteca nativa não foi copiada ao lado do binário. Rode dotnet publish em vez de só dotnet build.
BadImageFormatException no Windows Mismatch de arquitetura — implemente o build correto win-x64 ou win-arm64.
OfficeOxideException com código Unsupported em .doc Confirme a extensão em minúsculas ou passe o formato explicitamente via FromBytes.
Falta símbolos após trimming Adicione OfficeOxide em <TrimmerRootAssembly>.
macOS “não pode ser aberto porque o desenvolvedor não pode ser verificado” Rode xattr -d com.apple.quarantine /path/to/liboffice_oxide.dylib ou assine o bundle.

Veja também