Просмотр и печать файлов
Компонент q-file-viewer открывает документ в модальном окне или прямо на странице, печатает его
и отдаёт пользователю на скачивание. PDF и DOCX показываются в окне просмотра, остальные форматы
предлагаются к скачиванию.
Живые примеры, которые можно потыкать, — на демо-портале (opens in a new tab).
Быстрый старт
Установите библиотеку:
npm i @diasoft/qpalette-file-viewerПодключите функциональность на корневом уровне приложения:
import { provideQFileViewer } from '@diasoft/qpalette-file-viewer';
provideQFileViewer();Добавьте в angular.json правило копирования воркера pdf.js — он разбирает документ в отдельном
потоке, чтобы интерфейс оставался отзывчивым:
{
"glob": "pdf.worker.min.mjs",
"input": "node_modules/pdfjs-dist/legacy/build",
"output": "assets/pdfjs-dist"
}Подключите модуль компонента и вставьте его в разметку:
import { QFileViewerModule } from '@diasoft/qpalette-file-viewer';
@Component({
imports: [QFileViewerModule],
// ...
})Относительный путь отсчитывается от адреса вашей сборки — подробнее в разделе Откуда отсчитывается путь к файлу.
Откуда отсчитывается путь к файлу
Путь к документу разбирается по правилам:
| Что передали | Куда ведёт |
|---|---|
reports/report.pdf — путь без ведущего assets/ (с 8.2.0) | файл в ассетах вашей сборки: /api/<сервис>/<компонент>/assets/reports/report.pdf |
assets/report.pdf | от адреса вашей сборки: /api/<сервис>/<компонент>/assets/report.pdf |
/assets/report.pdf | от корня сайта |
https://example.com/report.pdf | используется как есть |
Первое правило — общее для компонентов Q.Palette (Адреса собственных
ассетов); второе — особенность
просмотрщика: у него assets/… ведёт в вашу сборку, а не в рутовое приложение, как с 8.1.3.
Адрес сборки веб-компонента продукта — /api/<сервис>/<компонент>/. Поэтому файл, лежащий в
ассетах вашего микрофронтенда, указывается относительным
путём и находится независимо от того, на каком маршруте открыт экран:
<q-file-viewer pdf="reports/report.pdf" name="Отчёт за квартал"></q-file-viewer>Путь от корня (/assets/…) ведёт в ассеты рутового приложения, а не вашего компонента, — им
пользуйтесь, когда файл действительно лежит там. Документ с сервера или из соседнего сервиса
указывайте полным адресом либо получайте через сервис отчётов.
До 8.1.0 относительный путь разбирался от адреса открытой страницы: на вложенных маршрутах он вёл в несуществующий адрес, и обходились путём от корня. Если ваш код так и написан, он продолжит работать — правило для путей от корня не изменилось.
Какие файлы можно показать
Ссылка на файл передаётся в свойство, названное по формату. Каждое свойство добавляет свой пункт в меню скачивания.
<q-file-viewer
pdf="reports/report.pdf"
docx="reports/report.docx"
rtf="reports/report.rtf"
excel="reports/report.xlsx"
></q-file-viewer>| Формат | Свойство | Просмотр в окне | Скачивание |
|---|---|---|---|
pdf | да | да | |
| DOCX | docx | да | да |
| DOC | doc | нет | да |
| RTF | rtf | нет | да |
| XLSX | excel | нет | да |
Свойство name задаёт заголовок окна просмотра, fileName — имя файла при скачивании:
<q-file-viewer
pdf="reports/report.pdf"
name="Отчёт за квартал"
fileName="report_q4"
></q-file-viewer>Кнопки и окно просмотра
По умолчанию компонент показывает одну кнопку — «Просмотр». Кнопки печати и скачивания включаются свойствами; если файлов несколько, у кнопки скачивания появляется меню с выбором формата.
<q-file-viewer
pdf="reports/report.pdf"
showLoadButton="true"
showPrintButton="true"
></q-file-viewer>Подписи и иконки настраиваются свойствами *Caption и *Icon, оформление — *ButtonClass.
Подойдёт любой класс кнопки PrimeNG: размеры p-button-sm, p-button-lg; стили p-button-raised,
p-button-rounded, p-button-text, p-button-outlined; severity p-button-secondary,
p-button-success, p-button-info, p-button-warning, p-button-danger, p-button-help,
p-button-contrast. Классы комбинируются:
<q-file-viewer
pdf="reports/report.pdf"
viewIcon="pi pi-eye"
viewCaption="Открыть отчёт"
viewButtonClass="p-button-sm p-button-raised p-button-secondary"
></q-file-viewer>Свойство inline показывает документ прямо на странице, без модального окна и кнопок управления —
в этом случае задайте контейнеру высоту:
<div style="height: 600px">
<q-file-viewer pdf="reports/report.pdf" [inline]="true"></q-file-viewer>
</div>Встроенный просмотрщик остаётся в границах своего контейнера и не двигает страницу под собой — её прокрутка сохраняется и при первом показе документа.
До версии 8.0.39 просмотрщик при показе документа прокручивал страницу к себе: она открывалась не с начала, а на первой странице документа. Если обновиться нельзя, разместите просмотрщик в начале страницы или показывайте его по действию пользователя.
Печать и управление из кода
Метод print() отправляет документ на печать, не открывая окно просмотра. Печатается файл из
свойства pdf — для других форматов метод напишет предупреждение в консоль.
<button pButton label="Печать" (click)="viewer.print()"></button>
<q-file-viewer #viewer pdf="reports/report.pdf" [showViewButton]="false"></q-file-viewer>Метод open() открывает окно просмотра из вашего кода — тогда собственную кнопку компонента можно
скрыть:
<a href="javascript:void(0)" (click)="viewer.open()">Открыть отчёт</a>
<q-file-viewer #viewer pdf="reports/report.pdf" [showViewButton]="false"></q-file-viewer>Событие viewerClose срабатывает после закрытия окна просмотра:
<q-file-viewer pdf="reports/report.pdf" (viewerClose)="onViewerClose()"></q-file-viewer>В компонент можно передать собственные элементы управления — они отобразятся в нижней части окна просмотра:
<q-file-viewer pdf="reports/report.pdf">
<ng-template #qFileViewerFooter>
<button pButton label="Отклонить" severity="danger"></button>
<button pButton label="Подписать" severity="success"></button>
</ng-template>
</q-file-viewer>Отчёты
Сервис QJasperReportsService формирует отчёт в mdpreports и скачивает его файл из mdpfilestorage.
Ключ доступа подставляет перехватчик из @diasoft/qpalette-auth, поэтому ни логин с паролем, ни токен
передавать не нужно.
Отдельной регистрации сервис не требует. Адреса сервисов строятся от базового адреса API: по умолчанию
берётся apiBaseUrl из конфигурации приложения, поэтому обычно ничего передавать не нужно. Если у отчётов
свой адрес — переопределите его при подключении библиотеки:
provideQFileViewer({ baseUrl: '/api/$service' });Подробнее о шаблоне адреса — в документации к библиотеке QUrlService.
Метод возвращает адрес готового файла — его можно сразу передать в свойство pdf.
import { Component, inject, signal } from '@angular/core';
import { QJasperReportsService } from '@diasoft/qpalette-file-viewer';
@Component({
selector: 'app-quarter-report',
templateUrl: './quarter-report.component.html',
})
export class QuarterReportComponent {
private readonly reports = inject(QJasperReportsService);
readonly pdf = signal('');
showReport(): void {
this.reports.createReportUrl({ reportName: 'quarter', period: '2026Q1' })
.subscribe((url) => this.pdf.set(url));
}
}<button pButton label="Сформировать отчёт" (click)="showReport()"></button>
<q-file-viewer [pdf]="pdf()" name="Отчёт за квартал"></q-file-viewer>Если отчёт нужен сразу при открытии страницы, подписка не нужна — отдайте поток в шаблон:
readonly pdf$ = this.reports.createReportUrl({ reportName: 'quarter', period: '2026Q1' });<q-file-viewer [pdf]="pdf$ | async" name="Отчёт за квартал"></q-file-viewer>Сервис QReportsService объявлен устаревшим и будет удалён в версии 9.0.0. Как перейти —
QReportsService → QJasperReportsService
с таблицей соответствия методов.
Тонкости: воркер pdf.js
Воркер — отдельный поток браузера, в котором разбирается PDF. Пока он занят разбором, поток интерфейса свободен: приложение продолжает отвечать на прокрутку и нажатия.
Файл воркера берётся из ассетов вашей сборки —
/api/<сервис>/<компонент>/assets/pdfjs-dist/. Поэтому версия
воркера всегда совпадает с версией pdfjs-dist в вашей сборке, и настраивать обычно нечего — надо
лишь скопировать файл правилом из раздела «Быстрый старт».
Если правило копирования не добавить
Документ всё равно откроется. Код разбора входит в сборку приложения, а файл в assets нужен только
для того, чтобы браузер мог запустить этот код в отдельном потоке: конструктор Worker принимает
адрес файла, а не модуль из сборки. Не найдя файл, просмотрщик выполнит тот же код в потоке
интерфейса и напишет об этом в консоль.
Разница — во времени открытия. Замер на документе в 120 страниц (2 МБ), три открытия подряд в одном браузере:
| Разбор документа | Время открытия |
|---|---|
| В отдельном потоке — воркере | ≈ 0,9 с |
| В потоке интерфейса | ≈ 1,5 с |
Для одностраничной справки разница незаметна, для многостраничного отчёта — уже видна, а прокрутка и нажатия во втором случае делят время с разбором.
Свойство workerPath
Нужно, когда файл лежит не по пути из раздела «Быстрый старт». Путь без ведущей косой черты отсчитывается от адреса вашей сборки, путь от корня сайта и полный URL используются как есть:
<!-- ассеты вашей сборки: /api/<сервис>/<компонент>/assets/pdfjs/pdf.worker.min.mjs -->
<q-file-viewer pdf="reports/report.pdf" workerPath="pdfjs/pdf.worker.min.mjs"></q-file-viewer>Путь общий для всех просмотрщиков вашего приложения: pdf.js хранит его в одной настройке на весь подключённый экземпляр библиотеки. Если задать разные пути нескольким компонентам, победит тот, что установлен последним. На соседние веб-компоненты это не влияет — у каждого своя сборка pdf.js со своей настройкой.
Справочник
Файлы
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
pdf | string | — | Ссылка на файл формата PDF |
docx | string | — | Ссылка на файл формата DOCX |
doc | string | — | Ссылка на файл формата DOC |
rtf | string | — | Ссылка на файл формата RTF |
excel | string | — | Ссылка на файл формата XLSX |
fileName | string | — | Имя файла при скачивании |
workerPath | string | assets/pdfjs-dist/pdf.worker.min.mjs от адреса своей сборки | Путь к воркеру pdf.js |
Окно просмотра
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
name | string | '' | Заголовок окна просмотра |
inline | boolean | false | Показывать содержимое без модального окна и кнопок управления |
modal | boolean | false | Затемнять фон под окном |
dismissableMask | boolean | true | Закрывать окно по клику мимо него |
maximizable | boolean | true | Разрешить разворот окна на весь экран |
showPdfToolbar | boolean | true | Панель инструментов PDF: поиск, нумерация страниц, масштаб |
showPrintButtonInViewer | boolean | true | Кнопка печати внутри окна просмотра |
showLoadButtonInViewer | boolean | true | Кнопка скачивания внутри окна просмотра PDF и DOCX |
Кнопки управления
| Свойство | Тип | По умолчанию | Назначение |
|---|---|---|---|
showViewButton | boolean | true | Показывать кнопку просмотра |
showPrintButton | boolean | false | Показывать кнопку печати |
showLoadButton | boolean | false | Показывать кнопку скачивания |
viewCaption | string | 'Просмотр' | Подпись кнопки просмотра |
printCaption | string | 'Печать' | Подпись кнопки печати |
loadCaption | string | 'Скачать' | Подпись кнопки скачивания |
viewIcon | string | — | Иконка кнопки просмотра, например pi pi-eye |
printIcon | string | — | Иконка кнопки печати |
loadIcon | string | — | Иконка кнопки скачивания |
viewButtonClass | string | — | CSS-классы кнопки просмотра |
printButtonClass | string | — | CSS-классы кнопки печати |
loadButtonClass | string | — | CSS-классы кнопки скачивания |
Методы и события
| Имя | Тип | Назначение |
|---|---|---|
open() | метод | Открывает окно просмотра |
print() | метод | Печатает документ, не открывая окно |
viewerClose | событие | Срабатывает после закрытия окна просмотра |