OfficeViewer.Avalonia
0.1.5
dotnet add package OfficeViewer.Avalonia --version 0.1.5
NuGet\Install-Package OfficeViewer.Avalonia -Version 0.1.5
<PackageReference Include="OfficeViewer.Avalonia" Version="0.1.5" />
<PackageVersion Include="OfficeViewer.Avalonia" Version="0.1.5" />
<PackageReference Include="OfficeViewer.Avalonia" />
paket add OfficeViewer.Avalonia --version 0.1.5
#r "nuget: OfficeViewer.Avalonia, 0.1.5"
#:package OfficeViewer.Avalonia@0.1.5
#addin nuget:?package=OfficeViewer.Avalonia&version=0.1.5
#tool nuget:?package=OfficeViewer.Avalonia&version=0.1.5
OfficeViewer.Avalonia
中文说明
OfficeViewer.Avalonia 是用于 Avalonia 的只读 Office/PDF 原生预览控件包,提供 DOCX、PPTX、XLSX 与常见 PDF 的连续流式预览。
控件外层保持透明,不会强制宿主窗口背景。请由应用在外层使用 Border、Panel 或主题容器决定背景、圆角与阴影。
参考项目
DOCX、PPTX、XLSX 的文件读取、关系解析、样式模型和连续布局设计参考了 vue-office-core 项目。本包将对应思路移植为 C# 的 Open XML 解析和 Avalonia 控件渲染;它不包含 Vue、JavaScript 或 WebView 运行时,也不是对 Vue 组件的直接包装。
PDF 预览是当前项目独立实现的纯托管常见子集解析器:它不捆绑 PDF.js、PDFium 或 PdfPig。支持范围请见“格式范围与限制”。
包含控件
| 文档格式 | 命名空间和控件 | 读取结果属性 |
|---|---|---|
| Word / DOCX | OfficeViewer.Avalonia.Docx.DocxViewer |
PageCount |
| PowerPoint / PPTX | OfficeViewer.Avalonia.Pptx.PptxViewer |
PageCount |
| Excel / XLSX | OfficeViewer.Avalonia.Xlsx.XlsxViewer |
SheetCount、SelectedSheetIndex |
OfficeViewer.Avalonia.Pdf.PdfViewer |
PageCount |
每个控件均提供可绑定的 byte[]? Document 属性。给 Document 赋新的文件字节数组会自动开始读取;将其清除或设为 null 会自动取消旧读取任务,并释放当前文档的模型、图像与可视资源。PPTX/PDF 仅会实例化可视页及少量相邻页,避免长文档持续占用图片内存。控件仍保留 LoadAsync 作为非绑定场景的便捷方法。
DOCX、PPTX 和 PDF 采用按视口异步物化:非可视页面仅保留轻量占位,滚动到附近时才创建文字、图形和图片控件,离开缓存范围后立即释放。
缩放
所有四个预览控件均支持按住 Ctrl 并滚动鼠标滚轮进行放大或缩小,也支持触摸屏双指捏合缩放。 不按 Ctrl 时,鼠标滚轮保持正常的上下滚动行为。
安装
从你的 NuGet 源安装:
<PackageReference Include="OfficeViewer.Avalonia" Version="0.1.5" />
本仓库本地构建后的包目录如下,可在 Visual Studio、Rider 或 NuGet.Config 中添加为本地源:
OfficeViewer.Avalonia.NuGet\artifacts\packages
Avalonia XAML 用法
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:docx="clr-namespace:OfficeViewer.Avalonia.Docx;assembly=OfficeViewer.Avalonia"
xmlns:pptx="clr-namespace:OfficeViewer.Avalonia.Pptx;assembly=OfficeViewer.Avalonia"
xmlns:xlsx="clr-namespace:OfficeViewer.Avalonia.Xlsx;assembly=OfficeViewer.Avalonia"
xmlns:pdf="clr-namespace:OfficeViewer.Avalonia.Pdf;assembly=OfficeViewer.Avalonia">
<Grid RowDefinitions="Auto,*">
<TextBlock Text="{Binding PageCount, ElementName=DocxPreview}" />
<Border Grid.Row="1" Background="White" Padding="8">
<docx:DocxViewer x:Name="DocxPreview"
Document="{Binding DocxDocument}" />
</Border>
</Grid>
</Window>
其他三种控件的声明方式:
<pptx:PptxViewer x:Name="PptxPreview"
Document="{Binding PptxDocument}" />
<pdf:PdfViewer x:Name="PdfPreview"
Document="{Binding PdfDocument}" />
<xlsx:XlsxViewer x:Name="XlsxPreview"
Document="{Binding XlsxDocument}"
SelectedSheetIndex="{Binding SelectedWorksheet, Mode=TwoWay}" />
SelectedSheetIndex 从 0 开始。XLSX 控件故意不内置工作表选择器,请绑定到你自己的按钮、ComboBox、选项卡或 ViewModel。工作簿读取完成后,SheetCount 会更新。
C# 加载与释放
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public sealed class OfficePreviewViewModel : INotifyPropertyChanged
{
private byte[]? _docxDocument;
private byte[]? _pptxDocument;
private byte[]? _xlsxDocument;
private byte[]? _pdfDocument;
private int _selectedWorksheet;
public byte[]? DocxDocument { get => _docxDocument; set => SetField(ref _docxDocument, value); }
public byte[]? PptxDocument { get => _pptxDocument; set => SetField(ref _pptxDocument, value); }
public byte[]? XlsxDocument { get => _xlsxDocument; set => SetField(ref _xlsxDocument, value); }
public byte[]? PdfDocument { get => _pdfDocument; set => SetField(ref _pdfDocument, value); }
public int SelectedWorksheet { get => _selectedWorksheet; set => SetField(ref _selectedWorksheet, value); }
public async Task OpenDocxAsync(string path) => DocxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenPptxAsync(string path) => PptxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenXlsxAsync(string path) => XlsxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenPdfAsync(string path) => PdfDocument = await File.ReadAllBytesAsync(path);
public void ReleaseDocuments()
{
// null automatically cancels loading and releases each viewer's resources.
DocxDocument = null;
PptxDocument = null;
XlsxDocument = null;
PdfDocument = null;
}
public event PropertyChangedEventHandler? PropertyChanged;
private void SetField<T>(ref T field, T value, [CallerMemberName] string? name = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return;
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Document、PageCount、SheetCount 是 Avalonia StyledProperty。请在 ViewModel 中将文档字节数组绑定到 Document;需要释放内存时也将绑定源设为 null,使控件和 ViewModel 都不再保留该字节数组。
可在代码中调用 LoadAsync(Stream) 读取流。控件不会关闭调用方传入的流,而会创建自己的字节快照并将其赋给 Document;MVVM 绑定仍建议使用 byte[]? Document。
NativeAOT
本包支持 NativeAOT。
格式范围与限制
- DOCX:WordprocessingML 段落、文字 Run、编号、图片、表格、常见形状/文本框和页面流式布局。
- PPTX:PresentationML 幻灯片、主题/样式继承、文字、图片、填充、渐变、常见形状及已支持图表的连续流布局。
- XLSX:工作簿/工作表关系、共享字符串/富文本、样式、合并单元格、图片、行列尺寸、颜色和当前工作表绑定。
- PDF:压缩对象流、Form XObject、文字/CMap 解码、带常见蒙版的图片、填充/线条/透明度,以及 WPS 水印标记。加密、签名、损坏文件或高级 PDF 图形/字体仍可能需要完整 PDF 渲染器,本包不会宣称完全兼容。
English
OfficeViewer.Avalonia is a set of read-only native Avalonia viewers for DOCX, PPTX, XLSX, and common PDF files. Documents use continuous scrolling rather than a flip-book UI.
The outer viewer surface is transparent. Hosts own the surrounding background, corner radius, and shadow by wrapping the control in a Border, Panel, or theme container.
Reference project
The file-reading flow, relationship parsing, style models, and continuous-layout design for DOCX, PPTX, and XLSX are informed by vue-office-core. This package ports those ideas to C# Open XML parsing and Avalonia-native rendering. It does not bundle Vue, JavaScript, or a WebView, and it is not a wrapper around Vue components.
The PDF viewer is this project's separate managed common-subset implementation. It does not bundle PDF.js, PDFium, or PdfPig. See “Format scope and limitations” for the supported subset.
Included controls
| Document | Namespace and control | Result count |
|---|---|---|
| Word / DOCX | OfficeViewer.Avalonia.Docx.DocxViewer |
PageCount |
| PowerPoint / PPTX | OfficeViewer.Avalonia.Pptx.PptxViewer |
PageCount |
| Excel / XLSX | OfficeViewer.Avalonia.Xlsx.XlsxViewer |
SheetCount, SelectedSheetIndex |
OfficeViewer.Avalonia.Pdf.PdfViewer |
PageCount |
预览截图 / Screenshots
以下截图来自 samples 目录中的实际控件运行效果。 / The following screenshots show the viewers running with the sample documents in the samples directory.
| 格式 / Format | 预览 / Preview |
|---|---|
| Word / DOCX | |
| PowerPoint / PPTX | |
| Excel / XLSX | |
AOT 演示程序 / AOT demo
仓库 samples/samplesAot.exe 是基于当前控件源码构建的 Windows NativeAOT 演示程序。双击即可启动;也可以把 .docx、.pptx、.xlsx 或 .pdf 文件路径作为第一个命令行参数传入,启动时直接预览该文件。 / samples/samplesAot.exe is a Windows NativeAOT demo built from the current viewer source. Double-click it to start, or pass a .docx, .pptx, .xlsx, or .pdf path as the first command-line argument to open that document on startup.
Every viewer exposes a bindable byte[]? Document property. Assign a new document byte array to start loading automatically; clear it or assign null to cancel stale loading and release the current document model, images, and visual resources. PPTX and PDF only materialize visible pages/slides plus a small adjacent buffer. LoadAsync remains available as a convenience method for non-binding scenarios.
DOCX, PPTX, and PDF materialize pages asynchronously around the viewport: off-screen pages keep only lightweight placeholders, while text, shapes, and images are created when they approach the viewport and released after leaving the cache window.
Zoom
All four viewers support zooming with Ctrl + mouse wheel and two-finger pinch gestures on touch screens. Without Ctrl, the mouse wheel continues to scroll the preview normally.
Install
Install from your NuGet source:
<PackageReference Include="OfficeViewer.Avalonia" Version="0.1.5" />
For a local build of this repository, add the following folder as a NuGet source:
OfficeViewer.Avalonia.NuGet\artifacts\packages
Avalonia XAML usage
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:docx="clr-namespace:OfficeViewer.Avalonia.Docx;assembly=OfficeViewer.Avalonia"
xmlns:pptx="clr-namespace:OfficeViewer.Avalonia.Pptx;assembly=OfficeViewer.Avalonia"
xmlns:xlsx="clr-namespace:OfficeViewer.Avalonia.Xlsx;assembly=OfficeViewer.Avalonia"
xmlns:pdf="clr-namespace:OfficeViewer.Avalonia.Pdf;assembly=OfficeViewer.Avalonia">
<Grid RowDefinitions="Auto,*">
<TextBlock Text="{Binding PageCount, ElementName=DocxPreview}" />
<Border Grid.Row="1" Background="White" Padding="8">
<docx:DocxViewer x:Name="DocxPreview"
Document="{Binding DocxDocument}" />
</Border>
</Grid>
</Window>
Create the other controls in the same way:
<pptx:PptxViewer x:Name="PptxPreview"
Document="{Binding PptxDocument}" />
<pdf:PdfViewer x:Name="PdfPreview"
Document="{Binding PdfDocument}" />
<xlsx:XlsxViewer x:Name="XlsxPreview"
Document="{Binding XlsxDocument}"
SelectedSheetIndex="{Binding SelectedWorksheet, Mode=TwoWay}" />
SelectedSheetIndex is zero-based. The XLSX control intentionally has no built-in worksheet selector; bind it to your own buttons, ComboBox, tabs, or view model. SheetCount updates after a successful workbook load.
Load and release in C#
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
public sealed class OfficePreviewViewModel : INotifyPropertyChanged
{
private byte[]? _docxDocument;
private byte[]? _pptxDocument;
private byte[]? _xlsxDocument;
private byte[]? _pdfDocument;
private int _selectedWorksheet;
public byte[]? DocxDocument { get => _docxDocument; set => SetField(ref _docxDocument, value); }
public byte[]? PptxDocument { get => _pptxDocument; set => SetField(ref _pptxDocument, value); }
public byte[]? XlsxDocument { get => _xlsxDocument; set => SetField(ref _xlsxDocument, value); }
public byte[]? PdfDocument { get => _pdfDocument; set => SetField(ref _pdfDocument, value); }
public int SelectedWorksheet { get => _selectedWorksheet; set => SetField(ref _selectedWorksheet, value); }
public async Task OpenDocxAsync(string path) => DocxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenPptxAsync(string path) => PptxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenXlsxAsync(string path) => XlsxDocument = await File.ReadAllBytesAsync(path);
public async Task OpenPdfAsync(string path) => PdfDocument = await File.ReadAllBytesAsync(path);
public void ReleaseDocuments()
{
// null automatically cancels loading and releases each viewer's resources.
DocxDocument = null;
PptxDocument = null;
XlsxDocument = null;
PdfDocument = null;
}
public event PropertyChangedEventHandler? PropertyChanged;
private void SetField<T>(ref T field, T value, [CallerMemberName] string? name = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return;
field = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
Document, PageCount, and SheetCount are Avalonia styled properties. Bind the document byte array from a view model to Document; set that binding source to null when releasing memory so neither the viewer nor the view model retains the bytes.
For code-behind or service code, LoadAsync(Stream) accepts a stream without taking ownership of it. The viewer creates its own byte snapshot and assigns it to Document; byte[]? Document remains the recommended MVVM binding API.
NativeAOT
This package supports NativeAOT.
Format scope and limitations
- DOCX: WordprocessingML paragraphs, runs, numbering, images, tables, common shapes/text boxes, and page-flow layout.
- PPTX: PresentationML slides, theme/style inheritance, text, pictures, fills, gradients, common shapes, and supported charts in continuous flow.
- XLSX: workbook/sheet relationships, shared strings/rich text, styles, merged cells, images, row/column sizes, colors, and active-sheet binding.
- PDF: compressed object streams, Form XObjects, text/CMap decoding, images with common masks, fills/lines/transparency, and WPS watermark artifacts. Password-protected, signed, malformed, or advanced PDF graphics/font features can still require a full PDF renderer and are intentionally not claimed as fully supported.
Layout
OfficeViewer.Avalonia.NuGet/
src/OfficeViewer.Avalonia/ Package source / 包源码
samples/PackageConsumer/ PackageReference-only consumer / 独立消费项目
scripts/pack-and-verify.ps1 Package verification / 打包验证
artifacts/packages/ Generated .nupkg and .snupkg files / 生成包
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
首个独立版本:DOCX、PPTX、XLSX 与托管 PDF 预览控件。Initial standalone package: DOCX, PPTX, XLSX, and managed PDF viewers.