A feature-rich PDF and image viewer control for Power Apps Model-Driven Apps. View, navigate, search, and interact with PDF documents and images stored in Dataverse file columns.
- PDF Rendering - High-quality PDF display using PDF.js
- Image Support - View JPG, PNG, GIF, BMP, WebP, and other image formats
- Zoom Controls - Zoom in/out, fit to page, fit to width, custom percentages (25%-500%)
- Page Navigation - Previous/next, go to page, scroll-based tracking
- Search - Find text in PDFs with highlighted matches (Ctrl+F)
- Thumbnails Sidebar - Visual page thumbnails for quick navigation
- Outline/Bookmarks - Navigate PDF structure via bookmarks
- Rotation - Rotate documents left/right
- Dark Mode - Toggle between light and dark themes
- Fullscreen - Immersive viewing experience
- Print & Download - Native print and file download
- Keyboard Shortcuts - Full keyboard navigation support
- Auto-Discovery - Automatically finds file columns on the current record
- Responsive - Adapts to container size
-
Download the solution file:
- Managed:
Solutions/PdfViewer/bin/Release/PdfViewer.zip - Unmanaged:
Solutions/PdfViewer/bin/Debug/PdfViewer.zip
- Managed:
-
Go to Power Apps
-
Navigate to Solutions > Import solution
-
Select the downloaded
.zipfile and follow the import wizard
-
Open your Model-Driven App in the form designer
-
Add a new section or use an existing one
-
Click + Component > Get more components
-
Search for "PDF Viewer" and add it
-
Configure the control properties:
- Default File Column: Select which file column to display by default
- Show Toolbar: Toggle toolbar visibility
- Show Sidebar: Toggle sidebar visibility
- Default Zoom: Set initial zoom (auto, page-fit, page-width, or percentage)
- Theme: light, dark, or auto
This control must be bound to a Multiline Text column (Multiple Lines of Text). The control uses this binding to:
- Detect the current record context (entity name and record ID)
- Auto-discover File and Image columns on the entity
Important: The bound field is not used to store PDF content - it's only used for form context detection. You can bind to any existing multiline text field on your entity, or create a hidden one specifically for this control.
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
boundField |
Multiple (Multiline Text) | Yes | - | Must bind to a multiline text column for context detection |
defaultFileColumn |
Text | No | - | Logical name of the file column to display by default |
showToolbar |
Boolean | No | true | Show/hide the toolbar |
showSidebar |
Boolean | No | true | Show/hide the sidebar |
defaultZoom |
Text | No | auto | Initial zoom: auto, page-fit, page-width, or percentage |
theme |
Text | No | light | Theme: light, dark, or auto |
rows |
Number | No | 10 | Number of rows to display (controls height) |
| Property | Type | Description |
|---|---|---|
currentPage |
Number | Current page number being viewed |
totalPages |
Number | Total number of pages in the document |
selectedColumn |
Text | Currently selected file column name |
| Shortcut | Action |
|---|---|
Ctrl+F |
Open find panel |
Ctrl+P |
Print document |
Ctrl+G |
Next search match |
Ctrl+Shift+G |
Previous search match |
Enter |
Next search match (in find panel) |
Shift+Enter |
Previous search match (in find panel) |
Escape |
Close find panel / dialogs |
← / → |
Previous / Next page |
Page Up / Page Down |
Previous / Next page |
Home / End |
First / Last page |
Note: Keyboard shortcuts only work when the PDF viewer has focus.
- Standard PDF documents
- Text-based PDFs (searchable)
- Note: Scanned/image PDFs display but are not searchable
- JPEG (.jpg, .jpeg)
- PNG (.png)
- GIF (.gif)
- BMP (.bmp)
- WebP (.webp)
- SVG (.svg)
- TIFF (.tif, .tiff)
- Node.js 18+
- Power Platform CLI (
pac) - .NET 6.0 SDK
# Install dependencies
npm install
# Start development server
npm start
# Build control
npm run build
# Build solution (managed)
cd Solutions/PdfViewer
dotnet build --configuration Release
# Build solution (unmanaged)
dotnet build --configuration DebugPDF Viewer/
├── PdfViewerControl/
│ ├── components/
│ │ └── PdfViewer.tsx # Main React component
│ ├── services/
│ │ ├── PdfService.ts # PDF.js wrapper
│ │ └── DataverseService.ts # Dataverse Web API
│ ├── css/
│ │ └── PdfViewer.css # Styles with theme support
│ ├── index.ts # PCF lifecycle
│ └── ControlManifest.Input.xml
├── Solutions/
│ └── PdfViewer/ # Solution project
├── package.json
└── README.md
- PDF.js v4.10.38 - PDF rendering
- React 16+ (provided by PCF framework)
- Microsoft Edge (Chromium)
- Google Chrome
- Firefox
- Safari
The control includes optimizations for large documents (100+ pages):
- Virtual Scrolling - Only renders pages near the current view (reduces DOM from 100+ to ~9 nodes)
- Thumbnail Virtualization - Only renders visible thumbnails in sidebar
- Parallel Dataverse Requests - File/Image column discovery runs in parallel
- Memoized Search - O(1) lookup for search matches instead of O(n) filtering
- IntersectionObserver - Efficient page visibility detection
- requestIdleCallback - Non-blocking thumbnail rendering
- Search only works on text-based PDFs (not scanned/image PDFs)
- Annotations and form fields are read-only
MIT License - See LICENSE file
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
For issues and feature requests, please use the GitHub issue tracker.