Skip to main content

quds_office_editor 0.6.0 copy "quds_office_editor: ^0.6.0" to clipboard
quds_office_editor: ^0.6.0 copied to clipboard

Flutter Office surfaces on custom RenderBox: Word, Excel, PowerPoint, PDF viewer/editor, and a visual band-report designer with inspector and preview.

quds_office_editor #

pub package pub points MIT license Flutter RenderBox Flutter RTL

Embeddable Word, Excel, PowerPoint, PDF, and band-report designer surfaces for Flutter. Every document surface is a custom RenderBox. Not TextField. Not ListView. Not InteractiveViewer.

This is the interaction half of Quds Office Suite. Documents, formulas, pagination, PdfFile, pdf_widgets, and the .qrep report engine live in the pure-Dart quds_office_engine. You draw the ribbon, the file menu, and the window chrome. This package paints the document.

Report designer with the inspector

Word
Word: paginated canvas, BiDi caret, outline
Excel
Excel: virtualized grid, formulas, charts
PowerPoint
PowerPoint: stage, animations, slideshow
PDF
PDF: viewer and editor with thumbnails
Report preview
Report preview: paginated, engine-painted
RTL report
RTL reports: Arabic invoice, mirrored layout

Contents #


Install #

dependencies:
  quds_office_editor: ^0.6.0
flutter pub add quds_office_editor

Requires Flutter 3.44+ and Dart 3.12+. The engine comes along as quds_office_engine: ^0.6.0. Everything is exported from one library:

import 'package:quds_office_editor/quds_office_editor.dart';

Register the bundled fonts once, before the first frame:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await OfficeHostFonts.ensureRegistered();
  runApp(const MyApp());
}

The surfaces at a glance #

Widget Controller What it paints
QudsWordEditor WordEditorController Paginated pages, caret, tables, comments, headers and footers, OMML, pictures
QudsSheetEditor SheetEditorController Virtualized grid, formula bar, freeze panes, fill handle, charts
QudsSlideEditor SlideEditorController Slide stage, transform handles, snap guides, animations, slideshow
QudsPdfViewer PdfViewerController Read-only PDF pages, zoom, find, copy, links, rotation
QudsPdfEditor PdfEditorController The same canvas plus markup, form fill, page ops, incremental save
QudsReportDesigner ReportDesignerController Band-report canvas, toolbar, inspector, live preview, autocomplete
┌─ your Scaffold / desktop frame ──────────────────────────┐
│  toolbarBuilder  (optional — your ribbon)                │
│  ┌─────────────────────────────────────────────────────┐ │
│  │  QudsWordEditor / QudsSheetEditor / QudsSlideEditor │ │
│  │  QudsPdfViewer / QudsPdfEditor / QudsReportDesigner │ │
│  │  RenderBox  ·  IME  ·  selection  ·  undo           │ │
│  └─────────────────────────────────────────────────────┘ │
│  statusBarBuilder (optional)                             │
└──────────────────────────────────────────────────────────┘

Report designer #

A visual designer for .qrep band reports: invoices, statements, dashboards, vouchers. It works like Crystal Reports or FastReport, but it is pure Flutter RenderBox with no platform views. The templates, expressions, pagination, and exporters come from the engine's quds_reports.dart.

Report designer: chart selected, inspector showing chart data

Embed it #

import 'dart:io';
import 'dart:typed_data';

import 'package:flutter/material.dart';
import 'package:quds_office_editor/quds_office_editor.dart';

class ReportHost extends StatefulWidget {
  const ReportHost({super.key});

  @override
  State<ReportHost> createState() => _ReportHostState();
}

class _ReportHostState extends State<ReportHost> {
  final ReportDesignerController controller = ReportDesignerController()
    ..loadTemplate(ReportTemplates.byId('sales_invoice_ar')!);

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return QudsReportDesigner(
      controller: controller,
      inspectorWidth: 320,
      // Toolbar "Export" → PDF / XLSX / DOCX bytes, ready to save.
      onExport: (ReportExportFormat format, Uint8List bytes) {
        File('report.${format.name}').writeAsBytesSync(bytes);
      },
    );
  }
}

Open and save templates as plain XML:

final ReportDesignerController c =
    ReportDesignerController.fromXml(File('invoice.qrep').readAsStringSync());
File('invoice.qrep').writeAsStringSync(c.toXml());

c.loadXml(otherXml);                  // replace the open template
c.mockData = <String, Object?>{...};  // your own preview data (or inferred)
final Uint8List pdf = await c.export(ReportExportFormat.pdf);

QudsReportDesigner parameters:

Parameter Default Purpose
controller required Template, selection, undo, preview data
theme OfficeTheme.light Chrome tokens
inspectorWidth 300 Width of the property inspector
onExport null Receives exported bytes; hides Export when null
templates ReportTemplates.all Entries in the Templates menu
loadBundledFonts true Loads Liberation + Noto Naskh Arabic into the preview/export registry
focusNode / autofocus internal / true Keyboard focus

The canvas #

Arabic RTL invoice in the designer

  • Bands: report header, page header, group header/footer, detail (bound to a data set), page footer, report summary. Add, remove, and resize bands. Each band is labeled with its kind and data source.
  • Tools: text, image, table, barcode, QR code, line, rectangle, ellipse, and chart. Click to place or drag to size, then edit.
  • Direct manipulation: select, marquee, move across bands, resize with eight handles, and nudge with the arrow keys. Snapping uses the grid and smart guides.
  • Arrange: align left/center/right/top/middle/bottom, distribute, same width/height, bring forward and send back, copy/cut/paste, and duplicate.
  • Rulers in the template's unit (mm, cm, in, pt, px) and zoom (fit width, in, out).
  • RTL: Arabic templates mirror X in the designer (X (RTL)), shape text, and keep the authored coordinates in the file.
  • Inline editing on the canvas, with a caret, selection, and IME. The editor switches to black or white text when the element's own color would be unreadable on its fill (WCAG 4.5:1).

The inspector #

The inspector is designed so most edits need no typing. Each property carries metadata (ReportProperty.hint, presets, step, min, pair, glyph), and the inspector picks the right control from it:

Text inspector Color palette Chart inspector
Text element: paired X/Y and W/H steppers, align icons, switches, B/I/U Color popover: template palette, Office theme tints, standard colors Chart: type, legend/labels/grid switches, data binding, aggregation, sort
Property kind Control
Booleans (canGrow, wordWrap, legend, …) Switch
Small enums (align, vertical align, direction, unit, orientation, line style) Segmented control with painted icons or short labels
Larger enums (page size, chart type, aggregate, barcode kind) Dropdown
Lengths and numbers Field with ▲/▼ steppers; the step follows the unit (1 mm, 0.1 cm, 0.05 in); ↑/↓ while typing, Shift for ×10
Font size, family, number/date format Combo with presets (format presets show live samples, e.g. n2 → 1,234.50)
Colors Swatch + painted palette popover (No color, template palette, 60 theme tints/shades, 10 standard colors)
X/Y, Width/Height Paired fields on one row
Bold / Italic / Underline Toggle glyph row

Sections (Layout, Text, Font, Box, Chart, Data, Style, Report, Variables, Page, Palette, Diagnostics) collapse independently. The title badge shows the element kind and its band. Diagnostics list template problems with severity icons.

Report settings, variables, page, and palette

Expressions and autocomplete #

Text and expression properties use {{ … }} placeholders: {{Data.customer.name}}, {{item.qty * item.price | n2}}, {{SUM(item.total) | currency:LYD}}, {{TAFQEET(Data.total, 'LYD')}}. While you type, a painted popup suggests data fields (inferred from the preview data), functions with signatures, System.*, Group.*, Variables.*, format specs after |, and currency codes.

Autocomplete inside {{ }}

↑/↓ choose, Enter/Tab insert, Esc closes, Ctrl+Space opens it anywhere. Functions insert NAME() with the caret inside.

Templates and variables #

Templates menu

  • Templates: the toolbar menu loads any ReportTemplates.all entry with its sample data: Arabic VAT invoice, English commercial invoice, sales dashboard, account statement, inventory status, receipt voucher. A blank report is also available. Pass your own list in templates:.
  • Variables: typed template variables (text, number, boolean, date, list, expression) are added and edited in the inspector when nothing is selected. The Variables menu inserts {{Variables.x}} at the caret or as a new text box. Renaming a variable rewrites its references. Values are validated against the type.

Preview and export #

Live preview

F5 (or Preview) swaps the canvas for ReportPreviewSurface: real pagination from the engine, painted from glyph outlines, with page navigation. Export produces PDF (vector charts, embedded subset fonts), XLSX (typed cells, native Excel charts), or DOCX (native Word charts and tables) through onExport or controller.export(format).

Keyboard #

Keys Action
Arrows Nudge by the grid size (1 mm when snapping is off)
Shift+Arrows Fine nudge (0.1 mm)
Tab / Shift+Tab Select the next / previous element
Ctrl+Z / Ctrl+Shift+Z or Ctrl+Y Undo / redo
Ctrl+C / X / V / D / A Copy / cut / paste / duplicate / select all
Delete, Backspace Remove selection
F2, Enter, or double-click Edit text in place
Esc Cancel edit, close popup, leave a tool, or clear selection
F5 Toggle design / preview (Esc also leaves preview)
Ctrl+= / Ctrl+- / Ctrl+0 Zoom in / out / fit width
Ctrl+Space Open autocomplete
↑/↓ in a numeric field Step the value (Shift for ×10)

Quds Report Studio app #

The repository includes a standalone desktop app built on this widget: apps/quds_report_studio. It has frameless window chrome (move, resize, maximize), New/Open/Save/Save as, recent files, an unsaved-changes guard, and a status bar with live diagnostics.

cd apps/quds_report_studio
flutter run -d linux   # or windows, macos

Why a custom RenderBox #

A real Office canvas is one engine. Caret, BiDi, IME, pagination, tables, selection, and zoom must agree on the same coordinates.

Flutter’s text widgets are excellent for forms. They are the wrong primitive for a paginated Word page, a virtualized sheet, a slide stage with motion, or a PDF page whose text runs live in unrotated crop space.

Surface Controller What it paints
QudsWordEditor WordEditorController Paginated pages, caret, tables, comments, headers and footers, OMML, pictures
QudsSheetEditor SheetEditorController Virtualized grid, formula bar, freeze panes, fill handle, charts
QudsSlideEditor SlideEditorController Slide stage, transform handles, snap guides, animations, slideshow
QudsPdfViewer PdfViewerController Read-only PDF pages, zoom, find, copy, links, rotation
QudsPdfEditor PdfEditorController The same canvas plus markup, form fill, page ops, incremental save
┌─ your Scaffold / desktop frame ──────────────────────────┐
│  toolbarBuilder  (optional — your ribbon)                │
│  ┌─────────────────────────────────────────────────────┐ │
│  │  QudsWordEditor / QudsSheetEditor / QudsSlideEditor │ │
│  │  QudsPdfViewer / QudsPdfEditor                      │ │
│  │  RenderBox  ·  IME  ·  selection  ·  undo           │ │
│  └─────────────────────────────────────────────────────┘ │
│  statusBarBuilder (optional)                             │
└──────────────────────────────────────────────────────────┘

Host chrome stays outside the widget. The page, grid, stage, and PDF stack are custom paint.


Languages and writing directions #

The editor is built for many languages and many writing directions, not a single locale.

  • IME composition — Latin, Arabic, Hebrew, CJK, and other system IMEs compose on the custom caret. There is no EditableText on the page.
  • Logical caret, visual runs — the caret walks grapheme clusters. Paint follows the engine’s UAX #9 BiDi and Arabic shaping.
  • Paragraph and section direction — LTR, RTL, and mixed documents. Windows and Linux Ctrl+Shift side shortcuts flip paragraph direction (officeParagraphDirectionFromSides).
  • Sheet direction — worksheets display right-to-left or left-to-right.
  • PDF text — selection grows from the visual edge of an RTL run. Search folds Arabic presentation forms, alef variants, and diacritics so a typed query can meet a shaped content stream. A rotated watermark is painted as one shaped string on the host face, not as upright letters.
  • Chrome locale — OfficeStrings is a typed string table. Ship OfficeStrings.english, OfficeStrings.arabic, or your own translations. The canvas does not hardcode UI copy.
  • Surface direction — OfficeSurfaceConfig.textDirection sets the default for chrome and new content. Users can still mix directions inside a file.
const OfficeSurfaceConfig(
  textDirection: TextDirection.rtl,
  strings: OfficeStrings.arabic,
);

The same document bytes open with the same layout in any host language. Locale changes chrome labels, not pagination.


Host fonts #

The package ships Liberation Sans, Serif, and Mono (Standard 14 / Arial / Times / Courier substitutes) and Noto Naskh Arabic. Register them once before paint:

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await OfficeHostFonts.ensureRegistered();
  runApp(const MyApp());
}

Aliases such as Helvetica, Arial, Calibri, Times New Roman, and Courier New resolve to those faces. When a PDF embeds its own /FontFile2, that face wins for glyph shape and advances. Raw CFF is wrapped as OTTO for the host loader. The engine does not rasterize CFF outlines itself. JPEG2000 stays unsupported. JBIG2 MMR generic regions decode; other JBIG2 stays a placeholder.


Word #

Word editor: paginated canvas, outline, comments pane

import 'dart:typed_data';

import 'package:flutter/widgets.dart';
import 'package:quds_office_editor/quds_office_editor.dart';

class WordHost extends StatefulWidget {
  const WordHost({super.key, this.bytes});

  final Uint8List? bytes;

  @override
  State<WordHost> createState() => _WordHostState();
}

class _WordHostState extends State<WordHost> {
  late final WordEditorController controller = widget.bytes == null
      ? WordEditorController(
          config: const OfficeSurfaceConfig(
            textDirection: TextDirection.ltr,
            strings: OfficeStrings.english,
            theme: OfficeTheme.light,
          ),
        )
      : WordEditorController.fromBytes(widget.bytes!);

  @override
  void initState() {
    super.initState();
    if (widget.bytes == null) {
      controller.insertHeading(text: 'New document');
    }
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return QudsWordEditor(
      controller: controller,
      toolbarBuilder: (context, c) {
        return const SizedBox.shrink(); // your Home ribbon
      },
    );
  }
}
final Uint8List docx = controller.saveBytes();

The Word canvas supports:

  • Logical caret and IME, without EditableText
  • Bold, italic, underline, color, highlight, superscript, subscript
  • Alignment, lists, indent, line spacing, LTR and RTL sections
  • Page size and orientation per section (portrait and landscape in one document; continuous column slices share one paper size)
  • Horizontal pan and side gutters when a landscape page is wider than the view
  • Interactive rulers (margins, indents, tabs)
  • Tables (resize, select cells, merge), pictures, charts
  • Comments, footnotes and endnotes pane, hyperlinks, headers and footers
  • Page breaks, section breaks, TOC
  • OMML equations
  • Find and replace, print, text statistics
  • Undo, redo, copy, cut, paste

Orientation is a section property. Toggling landscape updates the caret section and its continuous siblings, not a single laid-out page.


Excel #

Excel editor: virtualized grid, formula bar, chart, sheet tabs

final controller = SheetEditorController.fromBytes(xlsxBytes);

QudsSheetEditor(
  controller: controller,
  frozenRows: 1,
  frozenCols: 1,
);

The grid is virtualized (VirtualViewport) so large sheets stay light.

  • A1 selection, fill handle, row and column insert and delete
  • In-cell editor and formula bar (showFormulaBar)
  • Formula engine from the engine package (SUM, IF, VLOOKUP, …)
  • Freeze panes, RTL or LTR sheets, number formats
  • Embedded charts from the selection
  • Recalculation on edit; isolate open for large workbooks
controller.recalculateWorkbook();
final Uint8List xlsx = controller.saveBytes();

PowerPoint #

PowerPoint editor: stage, animation pane, slide sorter

final controller = SlideEditorController.fromBytes(pptxBytes);

QudsSlideEditor(controller: controller);

Edit mode:

  • Move, resize, and rotate with transform handles
  • Snap guides when edges align
  • Shape text with the same inline editor used in cells
  • Tables, pictures, charts, z-order
  • Entrance, emphasis, exit, and motion paths
  • Slide transitions (fade, push, wipe, Morph, and others)

Slideshow:

controller.startShow(from: 0);   // F5 in the studio example
controller.showNext();           // click / →
controller.showPrevious();       // reverse the last motion
controller.endShow();            // Esc

showPrevious() reverses that animation or that transition. A fly-in flies back out. A push slides back. A mid-fade retreats from the current frame. It is not a jump to the previous slide’s final state.


PDF viewer and editor #

PDF viewer: fit page, thumbnails, view options

QudsPdfViewer is display-only (viewing / selecting): zoom, find, copy, outline jump, follow URI and internal destinations. It has no saveBytes.

QudsPdfEditor extends the same canvas: highlights, notes, AcroForm values, page insert, delete, and rotate, XFDF, and incremental save.

final viewer = PdfViewerController.fromBytes(pdfBytes);
QudsPdfViewer(
  controller: viewer,
  options: const PdfViewerOptions(
    defaultPage: 0,
    fitPolicy: PdfFitPolicy.width,
    minZoom: 0.25,
    maxZoom: 4,
    enableSwipe: true,
    swipeHorizontal: false,
    pageFling: true,
    pageSnap: false,
    preventLinkNavigation: false,
    nightMode: false,
  ),
  onViewCreated: (c) {},
  onLoadComplete: (count) {},
  onPageChanged: (page, total) {},
  onRender: (page) {},
  onPageError: (page, error) {},
  onLinkHandle: (action) {},
);

final editor = PdfEditorController.fromBytes(pdfBytes);
editor.highlightSelection();
editor.rotateCurrentPage(90); // clockwise /Rotate, not a box swap
final Uint8List saved = editor.saveBytes();

Pass PdfViewerOptions for fit policy, zoom clamps, swipe axis, page snap / fling, night invert (viewer paint only), scrollbar visibility, and preventLinkNavigation (delivers the link to onLinkHandle / onFollowLink without opening the URI). onError is forwarded onto the controller so loadBytesAsync failures surface there. gestureRecognizers from WebView-style APIs are not needed — the canvas owns gestures.

The page is RenderPdfCanvas. Host chrome (File, View, Annotate, Form) stays outside the widget. Body-text reflow is out of scope.

What the canvas actually does #

Behavior Detail
Page stack Pages are stacked with a gap. goToPage scrolls. Thumbnails and the outline jump to a destination
Zoom Animated zoom about a focal point. Cached tiles stretch while the gesture is in flight, then raster at the settled scale
Rotation /Rotate is a clockwise quarter-turn of the view. Hit-testing maps view coordinates back into unrotated crop space before selection and links
Selection Drag, double-click word, triple-click run. RTL highlights grow from the right edge. The highlight belongs to the page that owns the runs — it does not stick to the next page or to the next file
Select all Ctrl+A / selectAll() selects every text run in the file
Select page Ctrl+Shift+A / selectPage selects every run on that page, not an x-band between the first and last carets
Copy Ctrl+C copies the logical text of the selection
Find Search walks the display-list runs, including a match that spans several runs. Hits are page-tagged. The current hit scrolls into view. Next and previous wrap
Arabic find Queries fold presentation forms, alef variants, and diacritics against the same fold of the page text
Links Internal destinations and http / https / mailto. Desktop hover shows a destination preview; the marker is a thin line above the target, not a bar through the heading
Link follow onOpenUri overrides the platform opener
New file loadBytesAsync clears selection and find marks, and the canvas drops any in-flight drag highlight

Opening a PDF and changing pages does not carry the previous selection onto the new page’s coordinates.

Page tools #

Assembly (merge, split, extract, stamp, numbers, crop) is PdfToolbox on the engine. The editor consumes the resulting bytes with loadBytesAsync. Stamp and Bates overlays in the toolbox are Helvetica. A shaped, rotated watermark belongs on pdf_widgets Watermark, not on the Latin stamp operator.

Rotate in the editor calls the same /Rotate model: 90° clockwise or counter-clockwise, accumulated and normalized, without rewriting MediaBox.


Theming, modes, and chrome #

const OfficeSurfaceConfig(
  mode: OfficeInteractionMode.editing, // or selecting, viewing
  theme: OfficeTheme.dark,
  textDirection: TextDirection.ltr,
  strings: OfficeStrings.english,
  showRulers: true,
  showFormulaBar: true,
  showGridlines: true,
  showSlideHandles: true,
  showFindChrome: false,
  showNotesPane: false,
  showNavigationPane: false,
  enableUndo: true,
);
Mode Caret / IME Selection Mutations
editing Yes Yes Yes
selecting No Yes No
viewing No No No

OfficeTheme.light, OfficeTheme.dark, and OfficeTheme.highContrast ship as starting palettes. Host chrome is your Material or Cupertino. Only the page, grid, stage, and PDF stack are custom paint.

OfficeStrings is a complete typed table (file, home, insert, layout, review, view, find, notes, PDF page commands, …). OfficeStrings.english and OfficeStrings.arabic are included. Provide another language by constructing OfficeStrings(...).

Density (OfficeDensity) and form factor (OfficeFormFactor) let a host tighten chrome on phone versus desktop without changing the document model.


Load, save, progress #

await controller.loadBytesAsync(
  bytes,
  password: password,
  onProgress: (p) => setState(() => label = p.stage),
);

final Uint8List out = controller.saveBytes(password: optionalPassword);

Heavy opens run through OfficeIsolateOpen so a large deck does not freeze the first frame. Password-protected OOXML packages open when a password is supplied. PDF open uses the same isolate path (OfficeIsolateOpen.pdf).

Export any Office controller’s model to PDF:

final Uint8List pdf = OfficePdfExport.fromBytes(controller.saveBytes());

PDF save is incremental (PdfIncrementalSave) so annotations and form values append to the original file instead of rewriting every stream.


What this package refuses to be #

The document surface is not a stack of Flutter text widgets.

Forbidden on the canvas Why
TextField / TextFormField / EditableText Caret, BiDi, and pagination must be one engine
SelectableRegion Selection is owned by the controller
ListView / SingleChildScrollView / InteractiveViewer Virtualization and zoom are custom

Use those widgets in your toolbar, find field, and dialogs. Do not drop them onto the page. The studio example’s find bar is host chrome; the PDF highlight itself is painted by RenderPdfCanvas.

Also out of scope, on purpose:

  • Editing PDF body text as if it were Word
  • OCR, and recovering Office layout from a PDF
  • CMS signature digest match (no RSA / system roots) and certified PDF/A
  • Rasterizing CFF or JPEG2000 inside the engine; JBIG2 beyond MMR generic regions

Studio example #

A full Office workspace (File, Home, Insert, Layout, Review, View, a sample library, and an OS window frame) lives under example/:

cd packages/quds_office_editor/example
flutter run -d linux   # or macos, windows, chrome

The studio includes a bilingual chrome and a PDF gallery that opens on report templates first — 100+ samples, category chips, each sample two pages (English then Arabic). It also covers pdf_widgets twins, Office export, face samples, and a PDF tools lab (PdfToolbox merge, split, extract, organize, rotate, overlays). Reopen a gallery sample after changing it; a file already open in the viewer is the bytes you loaded, not a live link to the gallery builder.

See example/README.md for a guided tour.


Architecture #

your chrome (ribbons, dialogs, file pickers)
        │
        ▼
QudsWordEditor / QudsSheetEditor / QudsSlideEditor / QudsPdfViewer / QudsReportDesigner
        │
        ▼
OfficeController  ·  PdfViewerController  ·  ReportDesignerController
        │
        ▼
quds_office_engine   models, layout, PdfFile, .qrep reports, export
File Role
office_editors.dart Office widgets, shortcuts, IME
pdf_editors.dart QudsPdfViewer / QudsPdfEditor
office_controller.dart Commands, selection, undo, load and save
pdf_controller.dart PDF page, selection, find, markup, save
office_theme.dart Tokens, modes, localizable strings
office_clipboard.dart Copy, cut, paste
render_word_canvas.dart Paginated Word RenderBox
render_sheet_grid.dart Virtualized sheet RenderBox
render_slide_stage.dart Slide and slideshow RenderBox
render_pdf_canvas.dart PDF page stack RenderBox
pdf_text_selection.dart Caret, RTL slices, page-owned highlights
pdf_find.dart Display-list search with Arabic folding
office_ruler.dart Interactive Word ruler
word_notes_pane.dart Footnotes and endnotes host pane
quds_report_designer.dart QudsReportDesigner widget, shortcuts, menus
report_designer_controller.dart Template editing, selection, undo, inspector metadata
render_report_designer.dart Band canvas RenderBox
render_report_inspector.dart Inspector RenderBox (sections, steppers, palette)
render_report_preview.dart Paginated preview RenderBox
report_completion_popup.dart {{ }} autocomplete popup

Design rules #

  • Engine owns the model — the editor never forks a second document format.
  • RenderBox only on the canvas — no scrolling or text widgets as the page.
  • Host owns chrome — ribbons, dialogs, and file pickers stay in your app.
  • Type-safe commands — undoable mutations go through the controller.
  • PDF selection is page-owned — a highlight is not a screen rectangle that follows the viewport.

License #

MIT. See LICENSE.

5
likes
150
points
820
downloads
screenshot

Documentation

API reference

Publisher

verified publisherquds.cc

Weekly Downloads

Flutter Office surfaces on custom RenderBox: Word, Excel, PowerPoint, PDF viewer/editor, and a visual band-report designer with inspector and preview.

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#flutter #office #editor #pdf #word

License

MIT (license)

Dependencies

flutter, quds_office_engine

More

Packages that depend on quds_office_editor