| name | xaf-office |
| description | XAF Office/Document Management Modules - FileAttachmentsModule with IFileData/FileAttachment patterns (XPO and EF Core), SpreadsheetModule for Excel editing with ISpreadsheetValueStorage, RichTextModule for Word-like editing with IRichTextDocumentProvider and mail merge, PdfViewerModule for PDF display, platform differences (Blazor vs WinForms), programmatic document manipulation. Use when adding file attachments, spreadsheet editing, rich text editing, or PDF viewing to DevExpress XAF applications. |
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 | .pdf | Blazor, WinForms |
File Attachments Module
NuGet Packages
<PackageReference Include="DevExpress.ExpressApp.FileAttachments" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.FileAttachments.Blazor" Version="25.1.*" />
<PackageReference Include="DevExpress.ExpressApp.FileAttachments.Win" Version="25.1.*" />
Setup
RequiredModuleTypes.Add(typeof(FileAttachmentsModule));
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
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);
}
}
EF Core Pattern — Single File Attachment
using DevExpress.Persistent.BaseImpl.EF;
public class Document : BaseObject {
public virtual FileAttachment Attachment { get; set; }
}
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
var attachment = objectSpace.CreateObject<FileData>();
using (var stream = File.OpenRead("report.pdf")) {
attachment.LoadFromStream("report.pdf", stream);
}
employee.Attachment = attachment;
objectSpace.CommitChanges();
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
public class Budget : BaseObject {
public Budget(Session session) : base(session) { }
private byte[] spreadsheetData;
[EditorAlias("SpreadsheetPropertyEditor")]
[Size(SizeAttribute.Unlimited)]
public byte[] SpreadsheetData {
get => spreadsheetData;
set => SetPropertyValue(nameof(SpreadsheetData), ref spreadsheetData, value);
}
}
public class Budget : BaseObject {
[EditorAlias("SpreadsheetPropertyEditor")]
public virtual byte[] SpreadsheetData { get; set; }
}
Programmatic Spreadsheet Manipulation
using DevExpress.Spreadsheet;
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";
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
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);
}
}
public class Article : BaseObject {
[EditorAlias("RichTextPropertyEditor")]
public virtual byte[] Content { get; set; }
}
Mail Merge
using DevExpress.XtraRichEdit;
using DevExpress.XtraRichEdit.API.Native;
using var server = new RichEditDocumentServer();
using var templateStream = new MemoryStream(article.Content);
server.LoadDocument(templateStream, DocumentFormat.OpenXml);
server.Document.MailMerge.DataSource = contacts;
server.Document.MailMerge.Execute();
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
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