xaf-office
XAF: Office / Document Management Modules
Available Modules
| Module | Class | File Type | Platforms |
|---|---|---|---|
| File Attachments | FileAttachmentsModule |
any file | Blazor, WinForms |
| Spreadsheet | SpreadsheetModule |
.xlsx | Blazor, WinForms |
| Rich Text | RichTextModule |
.docx, .rtf | Blazor, WinForms |
| PDF Viewer | PdfViewerModule |
Blazor, WinForms |
File Attachments Module
NuGet Packages
<PackageReference Include="DevExpress.ExpressApp.FileAttachments" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.FileAttachments.Blazor" Version="25.1.*" />
<!-- or for WinForms: -->
<PackageReference Include="DevExpress.ExpressApp.FileAttachments.Win" Version="25.1.*" />
Setup
// Module:
RequiredModuleTypes.Add(typeof(FileAttachmentsModule));
// Blazor Program.cs:
b.AddModule<FileAttachmentsModule>();
b.AddModule<FileAttachmentsBlazorModule>();
IFileData Interface
public interface IFileData {
string FileName { get; set; }
int Size { get; }
void LoadFromStream(string fileName, Stream stream);
void SaveToStream(Stream stream);
}
XPO Pattern — Single File Attachment
// Option 1: Built-in FileData (recommended)
using DevExpress.Persistent.BaseImpl;
public class Document : BaseObject {
public Document(Session session) : base(session) { }
private FileData attachment;
[Aggregated]
public FileData Attachment {
get => attachment;
set => SetPropertyValue(nameof(Attachment), ref attachment, value);
}
// EditorAlias auto-detected from IFileData
}
EF Core Pattern — Single File Attachment
using DevExpress.Persistent.BaseImpl.EF;
public class Document : BaseObject {
// FileAttachment is the EF Core equivalent of FileData
public virtual FileAttachment Attachment { get; set; }
}
// DbContext:
public DbSet<FileAttachment> FileAttachments { get; set; }
XPO Pattern — Multiple File Attachments (Collection)
public class Employee : BaseObject {
public Employee(Session session) : base(session) { }
[Aggregated]
[Association("Employee-Documents")]
public XPCollection<FileData> Documents => GetCollection<FileData>(nameof(Documents));
}
EF Core Pattern — Multiple Files
public class Employee : BaseObject {
public virtual IList<FileAttachment> Documents { get; set; }
= new ObservableCollection<FileAttachment>();
}
Programmatic File Access
// Load from stream
var attachment = objectSpace.CreateObject<FileData>();
using (var stream = File.OpenRead("report.pdf")) {
attachment.LoadFromStream("report.pdf", stream);
}
employee.Attachment = attachment;
objectSpace.CommitChanges();
// Save to stream
using (var stream = new MemoryStream()) {
employee.Attachment.SaveToStream(stream);
File.WriteAllBytes("output.pdf", stream.ToArray());
}
Spreadsheet Module
Setup
<PackageReference Include="DevExpress.ExpressApp.Spreadsheet" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.Spreadsheet.Blazor" Version="25.1.*" />
b.AddModule<SpreadsheetModule>();
b.AddModule<SpreadsheetBlazorModule>();
Business Object with Embedded Spreadsheet
// XPO
public class Budget : BaseObject {
public Budget(Session session) : base(session) { }
// Store spreadsheet as byte array
private byte[] spreadsheetData;
[EditorAlias("SpreadsheetPropertyEditor")]
[Size(SizeAttribute.Unlimited)]
public byte[] SpreadsheetData {
get => spreadsheetData;
set => SetPropertyValue(nameof(SpreadsheetData), ref spreadsheetData, value);
}
}
// EF Core
public class Budget : BaseObject {
[EditorAlias("SpreadsheetPropertyEditor")]
public virtual byte[] SpreadsheetData { get; set; }
}
Programmatic Spreadsheet Manipulation
using DevExpress.Spreadsheet;
// Read spreadsheet data from XAF object
byte[] data = budget.SpreadsheetData;
using var workbook = new Workbook();
using var stream = new MemoryStream(data);
workbook.LoadDocument(stream, DocumentFormat.Xlsx);
var sheet = workbook.Worksheets[0];
sheet.Cells["B2"].Value = 1234.56;
sheet.Cells["B3"].Formula = "=B2*1.23";
// Save back
using var outputStream = new MemoryStream();
workbook.SaveDocument(outputStream, DocumentFormat.Xlsx);
budget.SpreadsheetData = outputStream.ToArray();
objectSpace.CommitChanges();
Rich Text Module
Setup
<PackageReference Include="DevExpress.ExpressApp.RichTextEdit" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.RichTextEdit.Blazor" Version="25.1.*" />
b.AddModule<RichTextEditModule>();
b.AddModule<RichTextEditBlazorModule>();
Business Object with Rich Text
// XPO
public class Article : BaseObject {
public Article(Session session) : base(session) { }
private byte[] content;
[EditorAlias("RichTextPropertyEditor")]
[Size(SizeAttribute.Unlimited)]
public byte[] Content {
get => content;
set => SetPropertyValue(nameof(Content), ref content, value);
}
}
// EF Core
public class Article : BaseObject {
[EditorAlias("RichTextPropertyEditor")]
public virtual byte[] Content { get; set; }
}
Mail Merge
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
// Load template from byte[] stored in XAF object
using var server = new RichEditDocumentServer();
using var templateStream = new MemoryStream(article.Content);
server.LoadDocument(templateStream, DocumentFormat.OpenXml);
// Execute mail merge
server.Document.MailMerge.DataSource = contacts; // your data list
server.Document.MailMerge.Execute();
// Export result
using var outputStream = new MemoryStream();
server.SaveDocument(outputStream, DocumentFormat.OpenXml);
var mergedBytes = outputStream.ToArray();
PDF Viewer Module
Setup
<PackageReference Include="DevExpress.ExpressApp.PdfViewer" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.PdfViewer.Blazor" Version="25.1.*" />
b.AddModule<PdfViewerModule>();
b.AddModule<PdfViewerBlazorModule>();
Business Object with PDF
// XPO
public class Contract : BaseObject {
public Contract(Session session) : base(session) { }
private byte[] pdfContent;
[EditorAlias("PdfViewerPropertyEditor")]
[Size(SizeAttribute.Unlimited)]
public byte[] PdfContent {
get => pdfContent;
set => SetPropertyValue(nameof(PdfContent), ref pdfContent, value);
}
}
Blazor vs WinForms Differences
| Feature | Blazor | WinForms |
|---|---|---|
| File upload | DxUpload component | OpenFileDialog |
| Spreadsheet editor | Browser-based DevExpress Spreadsheet | XtraSpreadsheet (Win control) |
| Rich text editor | Browser-based Rich Text editor | XtraRichEdit (Win control) |
| PDF viewer | Browser-based PDF viewer | XtraPdfViewer (Win control) |
| Module class | *BlazorModule |
*WindowsFormsModule |
Auto-Added Document Actions
When an Office module property is present in Detail View, XAF automatically adds:
- Save (document) action
- Export / Print action (module-dependent)
- Load (from file) action
No extra controller code needed for basic file operations.
Source Links
- Document Management: https://docs.devexpress.com/eXpressAppFramework/113986/document-management
- File Attachments: https://docs.devexpress.com/eXpressAppFramework/113549/document-management/file-attachments-module
- Spreadsheet: https://docs.devexpress.com/eXpressAppFramework/400552/document-management/spreadsheet-document
- Rich Text: https://docs.devexpress.com/eXpressAppFramework/400315/document-management/rich-text-document
- FileData (XPO): https://docs.devexpress.com/eXpressAppFramework/DevExpress.Persistent.BaseImpl.FileData
- FileAttachment (EF Core): https://docs.devexpress.com/eXpressAppFramework/DevExpress.Persistent.BaseImpl.EF.FileAttachment
- IFileData API: https://docs.devexpress.com/eXpressAppFramework/DevExpress.Persistent.Base.IFileData
More from kashiash/xaf-skills
xaf
DevExpress XAF (eXpressApp Framework) master index. Use this skill first when working with any XAF topic to find the right sub-skill. Covers Blazor and WinForms, EF Core and XPO, versions v24.2 and v25.1. Sub-skills: xaf-xpo-models, xaf-ef-models, xaf-controllers, xaf-editors, xaf-custom-editors, xaf-nonpersistent, xaf-security, xaf-multi-tenant, xaf-web-api, xaf-validation, xaf-reports, xaf-dashboards, xaf-office, xaf-blazor-ui, xaf-winforms-ui, xaf-conditional-appearance, xaf-deployment, xaf-memory-leaks.
13xaf-winforms-ui
XAF WinForms UI platform - WinApplication setup, Ribbon vs Standard toolbar, WinForms-specific editors (XtraGrid, DevExpress controls), Detail View layout customization via Layout Manager, custom WinForms controls embedded in XAF views, background workers for thread-safe UI updates, splash screen customization, WinForms navigation (NavigationFrame), printing/preview in WinForms, ClickOnce/MSI deployment. Use when building or customizing XAF WinForms applications.
10xaf-blazor-ui
XAF Blazor UI platform - BlazorApplication setup in Program.cs, AddXaf/AddXafBlazor services, InvokeAsync thread safety (critical for Blazor Server), async controller actions pattern, Blazor-specific editors, embedding custom Razor components as ViewItems using IComponentContentHolder, JavaScript interop via IJSRuntime, Detail View layout customization (tabs/groups), programmatic navigation, error handling with UserFriendlyException, SignalR configuration. Use when building or customizing XAF Blazor Server applications.
10xaf-reports
XAF Reports Module (XtraReports v2) - ReportsModuleV2 setup for Blazor and WinForms, report storage (DB/filesystem/custom IReportStorageWebExtension), creating predefined reports in code (PredefinedReportsUpdater), data sources (CollectionDataSource/EntityServerModeSource), report parameters, programmatic export (PDF/Excel/Word), in-app designer, PrintAction, security permissions for report design vs view. Use when working with DevExpress XtraReports integration in XAF.
9xaf-editors
XAF built-in property editors and list editors - editor type mapping by data type, EditorAliases constants, [EditorAlias] attribute, [ModelDefault] for DisplayFormat/EditMask, ObjectPropertyEditor for inline sub-forms, list editor types (GridListEditor, DxGridListEditor, TreeListEditor, ChartListEditor), GridListEditor WinForms customization, DxGridListEditor Blazor customization, IModelListView/IModelColumn properties. Use when working with built-in XAF editors or customizing grid/list views.
8xaf-xpo-models
XAF XPO persistent object models - base classes (XPObject, XPBaseObject, XPCustomObject, BaseObject), key attributes (Persistent, Size, Indexed, Association, Aggregated), one-to-many/many-to-many/one-to-one relations, PersistentAlias calculated fields, Session access, optimistic locking, common pitfalls. Use when defining business objects with XPO ORM in DevExpress XAF.
7