# File Viewer full documentation corpus > Complete bilingual corpus. For targeted retrieval, use /llms.txt and the per-page /llms.mdx/.../content.md endpoints. # Changelog (/changelog) ## v3.1.2 - EPUB and Patch fixes, opt-in BPMN and XML views [#v312---epub-and-patch-fixes-opt-in-bpmn-and-xml-views] * Fixed #300: EPUB orientation follows the stable reader viewport instead of transient toolbar measurements, preventing repeated layout changes. Verified with the reporter's file and browser regression. * Fixed #304: side-by-side Patch previews keep matched rows aligned and compact, with a fixture that preserves valid patch syntax. * Added opt-in BPMN diagrams (#297) and XML XSD validation and XSLT document views (#305). Ordinary XML stays on the text path; existing Full packages do not acquire the optional engines. The Demo includes working samples. * Carried forward ZIP security fixes, IDML runtime assets, and dependency updates while keeping Vue 2.6/2.7 and existing Full behavior available. This release contains 89 npm targets: 88 mainline packages at `3.1.2` and `msdoc-viewer` at `0.2.9`. DOCX remains at `0.3.32` and styled-exceljs at `0.21.6`. Issues #227, #248, and #269 still lack their reporter files and are not claimed as verified fixes. ## v3.0.3 - Word revisions, browser integration, and mobile PDF fixes [#v303---word-revisions-browser-integration-and-mobile-pdf-fixes] * MapLibre 6.4.1 fixes the attribution HTML sanitizer bypass. Its worker stays bundled locally and survives map recreation. Update js-yaml, sharp and Vitest security versions; replace the unused Browserify toolchain with the specific build shims it supplied. * Standard preview packages pin JSZip 3.10.2 for cross-realm binary inputs and consistent build/cold-install behavior. * Core and renderers pin DOMPurify 3.4.15 for its XML sanitization hardening, avoiding duplicate cold-install versions without increasing size budgets. * Demo toolbar hover no longer changes the document inset or CAD export dimensions. * DOC preserves insertion/deletion records, paragraph marks and soft breaks. Word review modes switch without selecting the file again. Correct DOC line-spacing units and font slots restore the supplied sales contract without inventing revision marks. * Resized spreadsheet columns now scale and survive sheet changes. Offscreen search covers real XLS input, distant columns and merged cells. CFB recovery skips only unused broken MiniFAT chains; required workbook data is still validated. * iPhone Safari PDF navigation recovers after search and keyboard dismissal. Canceled PDF startup no longer leaves an unhandled Worker rejection. * Vue CLI/Webpack, Angular and nested Vite integrations use the correct browser entries and local PPTX Workers. Explicit asset paths retain priority. New AMD entries support RequireJS without changing the host's `define` or relying on a CDN. * HTML offers static preview and exact source views without running scripts or external requests. OFD resolves declared resources and namespaces and rejects invalid required pages without hanging. CAD adds permission-aware, watermarked PNG/JPEG view downloads and corrects DXF LINE and DWF/DWFx contrast. * PDF runtime patches carry verifiable source hashes; CHM, Adobe and Illustrator security fixes are reflected in distributed Workers. Independent component source builds include their required inputs, and publication resumes by dependency layer with integrity checks. The mainline target is `3.0.3` for 87 packages; `msdoc-viewer` advances to `0.2.6`. Upstream engines are DOCX `0.3.31`, styled-exceljs `0.21.6`, CAD `0.8.2` and DWF `0.6.7`. Vue 2.6/2.7 and existing Full capabilities remain supported; pako 3 stays deferred. This patch also includes the HTML views, AMD entry and CAD image-download features. The private XLS from #227, the deletion-revision file behind the #236 screenshot and the historical #57 OFD remain unavailable. Constructed fixtures and the supplied contract do not establish those originals as fixed. ## v3.0.2 — Corrected patch release for spreadsheet search, DOCX shapes, and CAD monochrome output [#v302--corrected-patch-release-for-spreadsheet-search-docx-shapes-and-cad-monochrome-output] This release supersedes 3.0.1. npm does not allow replacing packages that already have dependents, so the published 3.0.1 line cannot be completely retracted; affected 3.0.1 packages are deprecated after 3.0.2 is published. ### Issue fixes and regression coverage [#issue-fixes-and-regression-coverage] * Fixed #247: spreadsheet search now searches parsed workbook cells outside the current virtual window, loads the target window, and jumps to the matching cell. The real `apps/viewer-demo/public/example/excel.xls` sample passes the browser regression. * Fixed #250 by upgrading `@file-viewer/docx` to `0.3.29`, which corrects page-relative positioning for floating shapes. The reporter's `test.docx` was rendered locally with the shape content in the expected positions. * Completed #213/#245: the CAD monochrome policy is preserved from DWF through the CAD renderer and HTML/Print output without mutating source data. The real DWF regression passes. * Re-ran the #242 Vite/PDF CJK asset boundary, the #232 `postal-mime@3.0.0` EML parser cases, and the Vue 2.6 CLI 3 Office sample. Vue 2 remains in the release gate. ### Safe dependency updates [#safe-dependency-updates] * Adopted the safe Dependabot subset: `pako@2.2.0`, `proj4@2.22.0`, `vite-plugin-dts@5.1.0`, `cnfast@0.2.0`, and `prettier@3.9.6`. * pako 3 remains deferred because DICOM `Inflate` error/message semantics are consumed by `packages/renderers/dicom/src/inspect.ts`. Next 16.3.4 remains excluded because its `sharp-libvips` dependency fails the repository's LGPL license gate. ### Release composition [#release-composition] The frozen release contains 88 npm targets from one commit: 87 mainline packages at `3.0.2` and the historical `msdoc-viewer` alias at `0.2.5`. External engines remain `@file-viewer/docx@0.3.29` and `styled-exceljs@0.21.4`. ## v3.0.1 — Host peer frameworks, PDF CJK fallback, and EML header correctness [#v301--host-peer-frameworks-pdf-cjk-fallback-and-eml-header-correctness] ### Readable text previews [#readable-text-previews] * Added opt-in readable text previews (#235): logical-line wrapping works in regular and bounded virtual views, while structured files can use lazily loaded Prettier parser chunks with an explicit formatted-preview badge and original-source switch. The formatting byte limit is independent from large-text rendering, and original download bytes remain authoritative. ### CLI reliability and interaction [#cli-reliability-and-interaction] * Replaced free-form format/capability entry in the interactive create/add wizard with checkbox-style renderer and format-family rows. Capabilities included by the selected profile are visibly preselected and retained, while optional rows support individual numbers, ranges, select-all, and clear-extra commands. * Generated Vite 8 projects now declare and preflight Node `^20.19.0 || >=22.12.0` before `dev` or `build`, producing an actionable upgrade message on unsupported runtimes. Web Component events are created from the element's owning document realm with a compatibility fallback when global `CustomEvent` is unavailable. ### New format renderers [#new-format-renderers] * Added `@file-viewer/renderer-chm`: offline in-browser CHM help reading with a Rust/WASM unpacker and a sandboxed reader for table of contents, articles, and images. Nothing leaves the browser. * Added `@file-viewer/renderer-design`: offline Adobe design preview covering PSD/PSB layers, Illustrator native PGF and PDF-compatible surfaces, IDML/ICML/INX, INDD/XD, modern XFL animation, and swatch, brush, and resource files. It ships as an explicit opt-in package whose Worker, WASM, and font assets can be self-hosted. ### PDF [#pdf] * Fixed the 3.0 packaging failure reported in #242 (Vite 8 + pnpm 11 + Node 22): `@file-viewer/vite-plugin` has treated pdf assets as required since 2.4, and 2.4 passed because `@fontsource-variable/noto-sans-sc` was then a runtime dependency of `@file-viewer/renderer-pdf`. 3.0.0 moved that font to devDependencies, so an installed app had no font source to copy and the missing required asset aborted `vite build`, which made rolling back to 2.4 look like the fix. In 3.0.1 the presets that activate the pdf renderer own the font source (`preset-office` and `preset-all` declare the font package, `preset-standard` takes it from `@file-viewer/assets-standard`), the published `@file-viewer/renderer-pdf` tarball carries no font copy, and when no font source resolves the asset is optional, so the build logs a warning instead of failing and PDF rendering keeps relying on the fonts embedded in each document. The #242 and profile gates keep that ownership and optionality from drifting back. ### Email [#email] * Raised the EML parsing baseline to postal-mime `3.0.0` (#232): parts without a declared charset fall back to the header encoding, folded RFC 5322 headers unfold completely, repeated headers resolve first-wins, and `to`/`cc`/`bcc` keep their original order. ### Ecosystem package installation [#ecosystem-package-installation] * `@file-viewer/vue3` no longer installs the host framework: `vue` moved to `peerDependencies: ">=3.3 <4"`, matching the Vue 2.6, Vue 2.7, React, React Legacy, Svelte, and jQuery packages, and the build-time icon library moved to devDependencies so the only runtime dependency is `@file-viewer/core`. Applications pinned to a Vue version outside the old `^3.5.35` range previously received a second Vue copy and crashed on mount with `Cannot read properties of null (reading 'refs')`. * Added a host runtime contract gate: ecosystem components may only install File Viewer packages at runtime, must declare their host framework as a peer, and must keep the three Vue release lines disjoint. A cold-install check now compares resolved host framework paths immediately after install and fails with the duplicated copies listed instead of surfacing as a browser timeout. * The `msdoc-viewer` compatibility alias moved to `0.2.5` so it follows the 3.0.1 `@file-viewer/doc` line: the alias ships the Word renderer version it resolves to, and a frozen alias could no longer be published twice. This release freezes 88 npm targets: 87 mainline packages on `3.0.1` and the `msdoc-viewer` alias on `0.2.5`. ### Dependency security [#dependency-security] * The XMind parsing path no longer resolves `@xmldom/xmldom` 0.9.10, whose six advisories are reachable from `DOMParser.parseFromString` while previewing an untrusted file; a dependency override keeps the whole graph on 0.9.12, and the public boundary check verifies the override really lands (#246). ## v3.0.0 — Modular CLI, opt-in specialist formats, and security gates [#v300--modular-cli-opt-in-specialist-formats-and-security-gates] Released August 27, 2026. * Added `@file-viewer/cli`, `file-viewer-cli`, and `create-file-viewer` for new projects and existing `package.json` applications. It detects frameworks and build systems, selects framework versions, formats, presets, and assets, and supports npm, pnpm, Yarn, Bun, credential-free private registries, and integrity-checked offline tgz preparation. * Made `standard` the recommended common-format profile without changing the eight published Full contracts. Existing `*-full` packages keep their `preset-all` format matrix, APIs, and same-version offline assets. Explicit CLI `full` selection adds later specialist capabilities after showing their size, runtime, and license boundaries. * Kept DICOM and digital-signature containers out of unchanged Full dependencies. The optional DICOM renderer covers bounded local single-file, single-frame, and multi-frame preview for uncompressed, JPEG Lossless, JPEG-LS, and JPEG 2000 Lossless fixtures; it is not a diagnostic, PACS/DICOMweb, or multi-file-series viewer (#210). * Added an optional signature and evidence-container renderer for bounded CMS/CAdES, RFC 3161/5544, ASiC-S/E, RFC 4998, JWS, and public OpenPGP material. It uses a permissively licensed rPGP Worker/WASM path, contains no LGPL source, and reports parsing, digest/signature checks, trust, and legal validity as separate concepts (#206). * Fixed the reporter's five-slide PPTX layout sample, including DrawingML table bounds and insets, horizontal SmartArt text, complex shape geometry, and the PPTX Worker in Chromium, Firefox, and WebKit (#200). * Restored the reporter's Excel table theme, header, and alternating-row styles, and kept resized column widths across sheet switches. Invalid merge metadata and stable Office width handling received matching regressions (#211/#203). * Added nested email-attachment preview across React, React Full, React Legacy, and React Legacy Full, with malicious filename, buffer replacement, unmount, Worker, and Object URL cleanup coverage (#212). * Re-ran the #178 Office 365/WPS in-cell image, floating drawing, TIFF, Worker transfer, double-click lightbox, and optional column-resizing suite. * Hardened document-generated HTML/DOM boundaries for DOC, RTF, PPTX, Markdown, Mermaid, Drawing, PlantUML, and Typst. External links remain blocked by default; CSP and Trusted Types gates pass in Chromium, Firefox, and WebKit. * Froze 84 npm targets: 83 mainline packages use 3.0.0, while the historical `msdoc-viewer` compatibility package uses 0.2.4. The external maintained engines are pinned to `@file-viewer/docx@0.3.28` and `styled-exceljs@0.21.4`. * The release promotes only the exact tarballs produced by the frozen commit after builds, tests, security gates, cold installs, browser matrices, and `npm publish --dry-run`. Publishing does not rebuild or invent another stable version. ## v2.4.0 — Unified versions and frozen release candidates [#v240--unified-versions-and-frozen-release-candidates] Released August 25, 2026. * Unified the root, GitHub Release, and 56 regular npm packages at 2.4.0. The historical `msdoc-viewer` compatibility package uses 0.2.3. * Updated the Spreadsheet and iWork paths to `styled-exceljs@0.21.3`, including prototype-safe worksheet maps, bounded XML/tag handling, and safe serialization of document-provided HTML, CSS, links, images, and attributes. * Re-ran the #178 Office 365/WPS in-cell image, floating drawing, TIFF, Worker transfer, double-click lightbox, and optional column-resizing regressions. Version unification does not remove Excel column resizing. * Stable publishing now promotes the exact tarballs that passed the full build, cold-install, and npm dry-run rehearsal. A receipt pins the source commit, package set, byte sizes, and SHA-512 hashes; the publish command never rebuilds them. ## v2.3.2 — Multipage TIFF and Vite 8 chunking [#v232--multipage-tiff-and-vite-8-chunking] Released August 24, 2026. * Added a TIFF-only lazy UTIF.js path for CCITT Group 4 and bounded multipage rendering, with shared zoom, rotation, fit width, page state, and double-click or keyboard lightbox access (#208). * Limited encoded bytes, page count, dimensions, per-page pixels, and cumulative decoded pixels; progressive page conversion releases RGBA data and Object URLs without changing native PNG/JPEG/WEBP loading. * Switched Vite 8 projects to Rolldown `codeSplitting.groups` while retaining Rollup `manualChunks` on Vite 5–7 and preserving user groups, priorities, array outputs, and disabled code splitting (#209). * Re-ran the original #178 Office 365/WPS in-cell-image workbook through main-thread, Worker, TIFF drawing, and lightbox paths without removing Excel column resizing. * Published `@file-viewer/renderer-image@2.3.1`, `@file-viewer/vite-plugin@2.3.3`, `@file-viewer/preset-lite@2.3.1`, and the unified 2.3.6 All/Full/copy-assets line. This release includes every v2.3.1 security correction. ## v2.3.1 — Legacy DOC rendering security [#v231--legacy-doc-rendering-security] Released August 24, 2026. * Encoded document-provided font names and generated attributes in the legacy DOC HTML API. * Blocked external DOC links by default. Internal bookmarks remain available; explicit opt-in permits only HTTP(S), email, telephone, and safe relative links. * Sanitized DOC markup again at the mount boundary with DOMPurify 3.4.13 and inserted renderer CSS through `textContent`. * Kept the sanitizer in the DOC lazy path. Its minified gzip size is 10,923 bytes and a 15 KiB release gate prevents unbounded growth. * Published `@file-viewer/doc@2.3.1`, `msdoc-viewer@0.2.2`, `@file-viewer/renderer-word@2.3.2`, and the 2.3.4 Office/Full/copy-assets patch line. ## v2.3.0 — Office/iWork coverage and verified file fixes [#v230--officeiwork-coverage-and-verified-file-fixes] Released August 20, 2026. * Added stable Pages, Numbers, Keynote, WordPerfect, Hangul, DBF, FB2, XLA/XLAM, and POT routes to the generated 221-extension, 32-pipeline matrix. * Fully released the fixes tracked by #174, #178, #179, #195, #198, and #201-#204. #200 remains open because the original PPTX is still missing. * Fixed Excel Office 365 and WPS in-cell images, workbook drawings, saved column widths, Shadow DOM column resizing, and double-click image preview. A reporter-provided TIFF drawing is now decoded on demand in the browser across main-thread, Worker, and lightbox paths. * Updated the DOCX engine to `@file-viewer/docx@0.3.27` for complex frames, sections, positioned pages, and anchored content; the Worker cache key now matches the runtime. * Hardened PPTX Worker output, rendered Markdown, archive filename decoding, package dependencies, and offline Worker/WASM delivery. * Kept PPT-only CJK fonts and native WASM out of PPTX-only builds, and made Vite 5–8 resolve the `renderer-presentation/pptx` export subpath correctly (#205). * The source and GitHub release are v2.3.0. Immutable npm corrections use `@file-viewer/renderer-spreadsheet@2.3.2`, `@file-viewer/renderer-iwork@2.3.1`, `@file-viewer/renderer-word@2.3.1`, `@file-viewer/renderer-presentation@2.3.1`, `@file-viewer/vite-plugin@2.3.2`, and the 2.3.3 Office/Full/copy-assets line. TIFF drawing metadata is supplied by `styled-exceljs@0.21.2`. ## v2.2.9 — PPTX and Markdown rendering security [#v229--pptx-and-markdown-rendering-security] The npm packages were published August 13, 2026; the GitHub Release was finalized August 17, 2026. * Sanitized PPTX Worker HTML, SVG, inline styles, URLs, event attributes, scripts, and unsafe global CSS before they enter the preview DOM. * Sanitized Marked output with DOMPurify and hardened links opened in a new window with `noopener noreferrer`. * Added browser gates for malicious Markdown, synthetic PPTX Worker output, and real malicious PPTX files across normal and virtualized rendering paths. * Kept the published capability matrix at 54 npm targets, 208 extensions, and 25 preview pipelines. ## v2.2.8 — Large spreadsheets, OFD first paint, and PPT watermark polish [#v228--large-spreadsheets-ofd-first-paint-and-ppt-watermark-polish] Released August 11, 2026. * Bounded spreadsheet auto-width sampling so large workbooks no longer require a complete row scan during every fit operation. * Disabled OFD transform transitions until initial layout stabilizes, removing the first-frame jump while preserving reduced-motion behavior. * Reduced the open-source binary PPT watermark to a single bottom-right mark while preserving the engine's mandatory licensing boundary. * Hardened release automation around npm timeouts, uncertain registry state, and interrupted uploads. ## v2.2.7 — PDF zoom anchoring and legacy Word tolerance [#v227--pdf-zoom-anchoring-and-legacy-word-tolerance] Released August 11, 2026. * Kept PDF zoom anchored to the current visible area instead of allowing the document to drift behind navigation. * Improved tolerance for HTML-in-WordDocument legacy DOC files. * Shipped the fixes consistently across npm, GitHub Releases, component repositories, the demo, documentation, website, and Docker images. ## Complete history [#complete-history] * [Browse all GitHub Releases](https://github.com/flyfish-dev/file-viewer/releases) * [Read the complete Chinese changelog](/zh/changelog) * [Verify the current format matrix](/guide/formats) --- # Support File Viewer (/donate) File Viewer remains Apache-2.0 open source. Sponsorship helps fund compatibility work, documentation, examples, offline assets, and long-term maintenance. * [GitHub Sponsors](https://github.com/sponsors/wybaby168): one-time or recurring sponsorship through GitHub. * [WeChat / Alipay](https://dev.flyfish.group/sponsor?source=github): convenient one-time support for domestic users. * [Enterprise support](https://dev.flyfish.group/shop): private deployment, custom compatibility work, and requirements with committed response expectations. GitHub Sponsors is received by [@wybaby168](https://github.com/wybaby168), the primary maintainer of File Viewer. Sponsorship supports open-source maintenance and does not include a service-level agreement unless a published tier explicitly says otherwise. [查看中文说明](/zh/donate) --- # BPMN diagrams (/guide/bpmn) Available in 3.1.2 and later. BPMN is an explicit opt-in; Full packages keep their existing dependency set. Install `@file-viewer/renderer-drawing` and its optional peer `bpmn-js@18.28.0`, then register it with any standard component: ```ts import { mountViewer } from '@file-viewer/web' import { bpmnRenderer } from '@file-viewer/renderer-drawing/bpmn' mountViewer(document.querySelector('#viewer'), { url: '/documents/process.bpmn', filename: 'process.bpmn', options: { renderers: [bpmnRenderer] } }) ``` The read-only view renders BPMN 2.0 XML with BPMN DI layout. Use its toolbar to switch between the diagram and original source, pan, zoom, fit the diagram, or select another diagram in the same file. Source mode does not execute XML or embedded process scripts. Missing layout and malformed files produce a visible diagnostic while keeping the source available. `createBpmnRenderer({ initialView: 'source', maxFileBytes: 5 * 1024 * 1024 })` starts with source view and a smaller input limit. The default limit is 20 MiB. This is not a modeler or workflow execution engine; it does not invent missing diagram coordinates. The upstream bpmn.io license requires its watermark to stay visible. The optional dependency's license is not replaced by File Viewer's Apache-2.0 license. See the renderer's `THIRD_PARTY_NOTICES.md` for the exact terms. If your application overlays a floating toolbar at the bottom, set `--file-viewer-content-end-inset` on the viewer host to the occupied height. The diagram reserves that space without modifying the upstream watermark. The Demo checks that its controls do not cover the logo or link. The Demo's **BPMN diagram and source** sample is independently constructed and redistributable. Issue attachments are tested locally, not automatically republished as demo files. --- # File Viewer CLI (/guide/cli) Use `npx file-viewer-cli@latest ...` for a zero-install command: this single-bin carrier delegates to the exact same-version `@file-viewer/cli`. After adding the scoped package to a project, use its local `file-viewer` executable directly.
Create
Choose a framework, a validated runtime version, a format profile, extra formats, package manager, and asset location.
Add
Inspect an existing package.json project, show the complete plan, install exact packages, and wire the generated integration entry.
Assets
Deploy only selected capability assets or preserve the complete historical copy-assets command and Full-package contract.
Prepare
Build an integrity-checked local tgz directory from an explicit npm or private registry with bounded concurrency.
## Start here [#start-here] Run the interactive project creator: ```bash npm create file-viewer@latest my-viewer # or pnpm create file-viewer my-viewer ``` The wizard shows the framework, profile, File Viewer release, validated framework versions, and optional formats before it asks for final confirmation. Cancelling or answering no leaves the project unchanged. For a reproducible non-interactive run, pass every decision explicitly: ```bash npx file-viewer-cli@latest create my-viewer \ --framework vue3 \ --profile standard \ --formats pdf,docx,xlsx,pptx \ --package-manager pnpm \ --non-interactive \ --yes ``` `--yes` is the write and installation confirmation for `create`, `add`, and `install`. Without it, non-interactive runs print the plan and do not install packages or write files. ## Choose a framework and version [#choose-a-framework-and-version] | CLI value | Generated integration | Version choice | | -------------- | ------------------------------------------------------ | -------------------------------------------------- | | `web` | Vanilla JavaScript plus the File Viewer Custom Element | Browser template | | `vue3` | Native Vue 3 component | Validated Vue 3 version from the installed catalog | | `vue2.7` | Native Vue 2.7 component | Validated Vue 2.7 version | | `vue2.6` | Native Vue 2.6 component | Validated Vue 2.6 version | | `react` | React 18 or 19 component | Choose a validated React 18/19 version | | `react-legacy` | React 16.8/17-compatible component | Validated legacy React version | | `svelte` | Native Svelte action/component setup | Choose a validated Svelte 3, 4, or 5 version | | `jquery` | jQuery plugin integration | Validated jQuery version | The interactive wizard lists exact versions frozen in the installed CLI catalog. In CI, use `--framework-version `. The generated Vite and framework-plugin versions are selected as one tested template; the CLI does not combine arbitrary runtime versions. ## Choose a profile [#choose-a-profile] | Profile | What it means | Recommended use | | ------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | | `standard` | Common Word, PDF/OFD, modern PPTX, Spreadsheet, Archive, Email, Text, Image, and Media capabilities with a selective asset pack | Recommended default for new applications | | `lite` | Text, Markdown/code, image, audio, and video | Small attachment previews | | `office` | The established Office preset, including its compatibility formats | Existing Office-focused integrations that need that exact preset contract | | `engineering` | The established engineering preset | CAD, 3D, EDA, Geo, and engineering attachments | | `all` | The published `preset-all` compatibility matrix | Existing modular integrations that explicitly use `preset-all` | | `full` | The matching historical `@file-viewer/*-full` package plus every later opt-in capability in the CLI catalog | Explicit all-capability setup when install size is acceptable | | `custom` | No fixed preset; add only selected format/capability packages | Strict dependency control |
Standard and Full are different contracts. `standard` is the recommended common-format default. The eight published `@file-viewer/*-full` packages keep their existing `preset-all`, runtime-asset, API, and format behavior; they are not silently changed to `standard`. Installing a Full package directly also does not auto-add later specialist packages. Choosing `--profile full` in this CLI keeps that Full package intact and adds the catalog's later explicit opt-ins. The current additional opt-ins are DICOM and digital-signature containers, so the CLI prints their weight, runtime, and license boundaries before confirmation.
Use `file-viewer plan` before choosing Full if download size matters: ```bash npx file-viewer-cli plan --framework react --profile full ``` The plan prints pinned packages, asset commands, heavy capabilities, license notices, and the current measured Full install range. It does not hide the Full cost behind a small top-level tarball number. ## Select formats and optional capabilities [#select-formats-and-optional-capabilities] Pass file extensions or capability ids during create/add: ```bash npx file-viewer-cli create viewer \ --framework react \ --profile standard \ --formats dwg,typst \ --yes ``` Inspect the catalog, then change an initialized project: ```bash npx file-viewer-cli list npx file-viewer-cli config add dwg --write npx file-viewer-cli config add dicom --write npx file-viewer-cli config add p7m --write npx file-viewer-cli config remove dwg --write npx file-viewer-cli plan npx file-viewer-cli install --yes ``` Heavy capabilities stay explicit in `standard`. The generated module imports only the fixed profile and selected additions, and runtime code still loads the matching renderer only after its format is opened. Every selected capability is registered in the same generated File Viewer configuration. DICOM, signed containers, Office files, PDF, and the rest use the same component, source input, lifecycle, and toolbar; the CLI never creates a second viewer page or a format-specific application entry. ### DICOM boundary [#dicom-boundary] `dicom` installs the optional local DICOM Part 10 renderer. It supports one local single-frame or multi-frame file, with bounded decoding and frame navigation. It does **not** provide multi-file series assembly, PACS/DICOMweb, MPR, segmentation, diagnostic interpretation, or an embedded OHIF application. ### Digital-signature boundary [#digital-signature-boundary] `p7m` (or the `signature` capability id) installs the optional local signature and evidence-container renderer. It inspects bounded CMS/CAdES, RFC 3161/5544 timestamps, ASiC-S/E, RFC 4998 evidence records, JWS, and public OpenPGP material in Workers. Cryptographic verification results are kept separate from certificate/key trust, qualified-signature status, policy compliance, and legal validity. Private-key operations, automatic decryption, remote `jku`/`x5u` fetching, full XAdES, and archival-policy validation are intentionally excluded. ## Create a new project [#create-a-new-project] The creator writes a small Vite project plus the File Viewer integration only after the plan is confirmed. Depending on the selected framework, the scaffold contains: * `package.json`, `index.html`, and `src/main.mjs`; * Svelte-specific `src/App.svelte` and `vite.config.mjs` when required; * `file-viewer.config.json`, the durable selection record; * `file-viewer.generated.mjs`, the default deterministic renderer registration module; * one import marker in a recognized application entry; * exact File Viewer dependencies and selected static assets. Preview a create without writing: ```bash npx file-viewer-cli create ./viewer \ --framework svelte \ --framework-version \ --profile standard \ --non-interactive \ --json ``` Use `--force` only after reviewing the dry run. It allows replacement of conflicting CLI scaffold/config/generated files; it is not a general permission to rewrite arbitrary application files. ## Add File Viewer to an existing project [#add-file-viewer-to-an-existing-project] Run `add` from the directory containing `package.json`, or pass that directory positionally: ```bash cd existing-app npx file-viewer-cli add # same operation from another directory npx file-viewer-cli add ./existing-app ``` The inspection covers: * the `packageManager` field first, then lockfiles; * Vue, React, Svelte, or jQuery dependencies and their declared runtime line; * an installed standard/preset/Full File Viewer profile; * Vite, Vue CLI, Webpack, Next.js, or Nuxt 2/3 build configuration; * a statically provable Vite `publicDir` or Nuxt `dir.public` / `dir.static`, plus the conventional Vue CLI and Next.js public directory; * existing File Viewer packages and catalog-version drift; * supported application entries that can import the generated module. It stops on ambiguous multiple frameworks or multiple installed profiles and asks for an explicit `--framework` or `--profile`. Dynamic or disabled public directories, multiple build configs, generic Webpack output, and unknown build systems produce concrete `manualSteps` and fail closed before installation or file writes; resolve the build target and pass a contained `--asset-target` to continue. If an existing framework version does not exactly match a validated scaffold version, the CLI preserves that runtime and prints a warning instead of silently rewriting the project. First review the detected state and commands: ```bash npx file-viewer-cli add . --profile standard --json ``` Then apply the same choice: ```bash npx file-viewer-cli add . --profile standard --yes --non-interactive npx file-viewer-cli verify --json ``` If no recognized application entry exists, `add` fails before installation or writes. Pass `--entry ` explicitly; do not inject the browser integration into an SSR-only entry. ## Configuration and generated integration [#configuration-and-generated-integration] The default `file-viewer.config.json` is project-relative and safe to commit: ```json { "schemaVersion": 1, "framework": "vue3", "profile": "standard", "formats": ["dwg"], "capabilities": [], "assetTarget": "public/file-viewer", "generatedModule": "file-viewer.generated.mjs", "locale": "en" } ``` | Field | Purpose | | -------------------------------- | ----------------------------------------------------------------------------- | | `framework` / `frameworkVersion` | Native integration and exact validated runtime target | | `profile` | Fixed preset, compatibility Full, or custom selection | | `formats` / `capabilities` | Explicit additions resolved through the frozen catalog | | `assetTarget` | Project-relative static directory; defaults to `public/file-viewer` | | `generatedModule` | Project-relative deterministic registration module | | `source` | Explicit registry or integrity-manifest offline directory | | `assetBaseUrl` | Explicit self-hosted/CDN runtime base; omitted means local same-origin assets | | `managedPackages` | Packages installed and owned by the CLI for safe heavy-dependency cleanup | | `locale` | CLI display language; JSON field names remain stable English keys | Generate or inspect the module separately: ```bash npx file-viewer-cli generate npx file-viewer-cli generate --write ``` Edit the config and regenerate rather than editing the generated file. User-owned files are not overwritten unless `--force` is explicit. ### Install recovery boundary [#install-recovery-boundary] Before a confirmed create/add/install package-manager step, the CLI atomically moves an existing project-local `node_modules` plus Yarn unplugged directory into an adjacent same-filesystem backup. It also snapshots `package.json`, existing lockfiles, Yarn PnP/install-state files, CLI config/generated integration, and the managed asset target. A handled package-manager or asset failure restores those bytes. If the atomic staging area cannot be established, the CLI fails before invoking the package manager. An abrupt process or host termination is outside the handled-error transaction and can leave `..file-viewer-install-*` beside the project. Inspect and restore that backup before rerunning; do not delete it blindly. Package-manager caches, including a project-local Yarn cache, are not rolled back. The CLI removes an obsolete heavy dependency only when `managedPackages` records that package as CLI-owned; an untracked declaration remains user-owned and is preserved. ## Asset commands and copy-assets compatibility [#asset-commands-and-copy-assets-compatibility] For a configured modular project, install or repair only the selected asset owners: ```bash npx file-viewer-cli assets --write ``` The original aggregate command remains available with the same package and bin: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer # Equivalent unified CLI entry npx file-viewer-cli copy-assets ./public/file-viewer ``` `file-viewer assets` also preserves the legacy copy behavior when no project config exists and legacy target/options are supplied. With a modular config present, it follows the selected asset plan instead; legacy flags cannot be mixed into that plan. | Legacy option/environment | Behavior | | ------------------------------- | ------------------------------------------------------------------------------- | | `[target-directory]` | Defaults to `public/file-viewer` | | `--renderers ` | Copies only named renderer asset groups | | `--no-clean` | Merge mode; this is the default and preserves unrelated files | | `--clean --confirm` | Replace only a dedicated safe `file-viewer` target after both flags are present | | `FILE_VIEWER_PUBLIC_DIR` | Default output directory | | `FILE_VIEWER_SKIP_ASSET_COPY=1` | Explicit CI skip | | `INIT_CWD` | Calling project root used by package-manager execution | The copy operation writes a manifest and receipt, validates required files, refuses path escapes/symlink targets, and does not overwrite unowned or externally modified assets. Existing Full-package commands keep delegating to the same-version implementation. A complete deployment of `@file-viewer/web-full/dist/` already contains its payload and needs no copy step. ## Private registry [#private-registry] Use HTTPS for a remote registry. Plain HTTP is accepted only for an explicit loopback host such as `127.0.0.1` during local testing: ```bash npx file-viewer-cli add . \ --profile standard \ --registry https://registry.example.com/ \ --cache-dir .file-viewer/package-cache \ --yes ``` The CLI does not silently use an ambient registry to fetch a missing copy-assets payload. Registry URLs containing a username or password are rejected. Configure authentication in the package manager's user/CI settings; do not place credentials in the project config or command history. `--registry` affects package acquisition only. Runtime Workers, WASM, fonts, and vendor assets remain self-hosted unless `--asset-base-url` is explicitly set to an approved origin. ## Prepare an offline tgz directory [#prepare-an-offline-tgz-directory] `prepare` and its `cache` alias download the exact File Viewer-owned dependency closure from an explicit registry. Downloads use concurrency `1-8`; every tarball is checked for a regular contained file, SHA-512, package identity, version, and dependency metadata before the result is committed atomically with `file-viewer-offline-manifest.json`. Integrity proves that bytes match the prepared manifest; it does not establish registry provenance, so use a registry you trust. Preview first: ```bash npx file-viewer-cli prepare \ --framework vue3 \ --profile standard \ --registry https://registry.npmjs.org/ \ --offline-dir .file-viewer/offline ``` Prepare after review: ```bash npx file-viewer-cli prepare \ --framework vue3 \ --profile standard \ --registry https://registry.npmjs.org/ \ --offline-dir .file-viewer/offline \ --concurrency 4 \ --yes ``` Use the verified directory in the target environment: ```bash npx file-viewer-cli add . \ --profile standard \ --offline-dir .file-viewer/offline \ --cache-dir .file-viewer/package-cache \ --yes \ --non-interactive ``` The offline directory contains the File Viewer-owned package closure, including compatibility packages required by the selected capabilities and the exact `@file-viewer/cli` used by `create-file-viewer`. It deliberately does not mirror unrelated framework packages or every third-party dependency already declared by the application. A fully air-gapped install must also provide the package-manager cache for those dependencies. npm, pnpm, Yarn Classic, and Yarn Berry receive generation-correct offline enforcement; Bun still requires a pre-populated cache. `--registry` and `--offline-dir` are mutually exclusive during installation. An existing offline directory is reused only when its requested roots, registry, filenames, versions, and integrity hashes all match. ## Help and language [#help-and-language] The CLI follows the system language when possible and supports four explicit help languages: ```bash file-viewer --help --lang en file-viewer --help --lang zh-CN file-viewer --help --lang ja-JP file-viewer --help --lang de-DE file-viewer create --help --lang en file-viewer add --help --lang zh-CN file-viewer doctor --help --lang ja-JP ``` Prompts and human-readable plan labels are localized. `--json` always uses stable English keys for CI and tooling. ### Commands [#commands] | Command | Purpose | Write gate | | --------------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------- | | `create [dir]` | Create a buildable project | Interactive confirmation or `--yes` | | `add [dir]` | Detect and integrate an existing project | Interactive confirmation or `--yes` | | `list` | List formats, renderer ids, packages, weights, licenses, and asset owners | Read-only | | `plan` | Print the exact install and asset plan | Read-only | | `init` | Create/update the project config | `--write` | | `config add/remove ` | Change explicit formats/capabilities | `--write` | | `generate` | Produce the deterministic integration module | `--write` | | `install` | Install exact packages and assets from the config | `--yes` | | `assets` | Install/repair configured assets, or use legacy mode without config | `--write` in configured mode | | `copy-assets` | Run the complete legacy copy-assets contract | Direct target write; cleanup also needs `--clean --confirm` | | `prepare` / `cache` | Build a verified local tgz directory | `--yes` | | `doctor` | Report dependency, entry, receipt, hash, and asset problems | Read-only | | `verify` | Run doctor and exit non-zero on errors | Read-only | ### Common options [#common-options] | Option | Purpose | | ------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | | `--project ` | Project root; positional `create/add ` is also supported | | `--framework ` | Select one of the eight framework integrations | | `--framework-version ` | Select an exact catalog-validated runtime template | | `--profile ` | `standard`, `lite`, `office`, `engineering`, `all`, `full`, or `custom` | | `--formats ` / `--capabilities ` | Add exact catalog entries | | `--package-manager ` | `npm`, `pnpm`, `yarn`, or `bun` | | `--package-manager-version ` | Exact package-manager version; records and distinguishes Yarn Classic from Yarn Berry | | `--asset-target ` | Contained project-relative asset directory | | `--output ` / `--config ` | Contained project-relative generated/config files | | `--registry ` | Explicit npm/private registry | | `--offline-dir ` | Integrity-manifest local tgz directory | | `--cache-dir ` | Controlled package-manager cache/store | | `--concurrency ` | `prepare/cache`: `1-8`; install package-manager network/script concurrency: `1-32` | | `--file-viewer-version ` | Require an exact match with the installed CLI catalog | | `--asset-base-url ` | Explicit approved runtime asset base; local remains the default | | `--json` | Machine-readable output with stable English keys | | `--non-interactive` | Disable prompts for CI | | `--yes` / `--write` | Explicit execution gates for their command groups | | `--force` | Replace conflicting CLI-managed config/generated/scaffold files after review | | `--dry-run` | Force every mutating command into a zero-write, zero-install preview even when `--yes` or `--write` is present | ## CI pattern [#ci-pattern] Keep planning and mutation separate: ```bash # Reviewable, no writes npx file-viewer-cli plan \ --framework vue3 \ --profile standard \ --formats dwg \ --json > file-viewer-plan.json # Apply exact catalog choices npx file-viewer-cli add . \ --framework vue3 \ --profile standard \ --formats dwg \ --non-interactive \ --yes # Fail CI when versions, entry imports, receipts, hashes, or assets drift npx file-viewer-cli verify --json ``` The JSON plan contains command and argument arrays instead of a shell-interpolated string, so automation can review and execute it without evaluating user-controlled shell text. ## Troubleshooting [#troubleshooting] | Message or symptom | What to do | | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | | `No package.json was found` | Run `create` for a new project, or run `add` from the package.json directory. | | Multiple framework/profile runtimes detected | Pass the intended `--framework` / `--profile`; the CLI will not guess. | | Requested File Viewer version differs from the catalog | Run the matching `@file-viewer/cli@` instead of mixing release catalogs. | | Existing framework is not a validated scaffold runtime | Keep it and review the warning, or choose a validated `--framework-version` deliberately. | | Missing copy-assets payload | Install the matching Full/copy package, configure an explicit registry, or provide the verified offline directory. | | Worker/WASM/font request returns HTML or 404 | Run the configured asset step, serve the target at the configured base, and verify MIME types on the production origin. | | Full install takes too long | Use `standard` or `custom`; prepare a private-registry/offline cache when Full is a real requirement. | Related: [modular profiles](/guide/v3-modular-profiles), [on-demand renderers](/guide/on-demand-renderers), [distribution](/guide/distribution), and [format truth](/guide/formats). --- # Comparison (/guide/compare) File Viewer is a pure frontend file preview component for internal tools, intranet systems, and private deployments. It is designed for quick business-file preview, triage, search, print, export, and self-hosted delivery. It is not a professional editor, and it does not promise native-app fidelity for every complex file. ## Open-source component vs commercial edition [#open-source-component-vs-commercial-edition] The open-source File Viewer and the commercial edition are not mutually exclusive. The open-source edition provides browser-native, multi-format, offline-ready preview. The commercial edition comes from the Flyfish Office product line and replaces the Office document capability with a self-developed native document engine, giving the same File Viewer integration a `file-viewer-pro` style Office experience. | Dimension | Open-source File Viewer | Commercial / file-viewer-pro path | | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Formats | 275 registered extensions (225 stable, 50 experimental) across 47 preview pipelines for PDF/OFD, Office/iWork, CAD, Typst, archives, email, ebooks, diagrams, media, 3D, data assets, Adobe design files, optional local DICOM, digital-signature containers, and byte inspection; common capabilities use presets while Adobe design, DICOM, signature, and binary-inspector formats stay explicit opt-ins | Strengthens the Word, Excel, and PowerPoint deep end. It can replace the Word / Spreadsheet / Presentation capability in `preset-office` while PDF, OFD, CAD, Archive, and other formats continue to use open-source renderers | | Fidelity | Optimized for readable, searchable, printable previews embedded in business systems. DOCX is currently flow-first, and Excel/PPTX target common preview needs rather than native Office pixel parity | The self-developed native document engine targets pagination, fonts, tables, shapes, headers/footers, comments/revisions, and complex deck layouts for contracts, reports, archives, and formal delivery | | Performance | A light core plus lazy renderer loading keeps most attachment centers responsive. Worker/WASM assets load on demand, while extreme large files should be validated with real samples | Large documents, large spreadsheets, and complex decks get Worker parsing, paginated or chunked rendering, virtual scrolling, caching, and memory tuning to keep the main thread smooth | | Licensing and support | File Viewer-authored code is Apache-2.0 and usable in commercial products. The independently versioned binary-`.ppt` engine, `@file-viewer/ppt`, keeps its own license and its public runtime is included in Demo/Full/CDN assets with the visible watermark. Community issues, sponsorship, and priority support can help, but final launch validation remains with the product team | Commercial licensing, private delivery, priority support, sample regression, custom compatibility work, and watermark-free PPT delivery for teams that need clear ownership and timelines | ## Replacing the Office capability [#replacing-the-office-capability] Commercial delivery provides a pluggable Office preset or renderer set. Your app keeps the same Vue, React, Svelte, jQuery, Web Component, or Vanilla JS component entry. Themes, watermarks, toolbar behavior, search, events, and non-Office formats stay on the same File Viewer contracts; only the Word, Excel, and PowerPoint rendering path switches to the commercial engine. ```ts import FileViewer from '@file-viewer/vue3' import engineeringPreset from '@file-viewer/preset-engineering' import { commercialOfficePreset } from './vendor/file-viewer-pro-office' const viewerOptions = { rendererMode: 'replace', preset: [ commercialOfficePreset, engineeringPreset ], theme: 'light' } ``` The actual package name and delivery channel depend on the commercial license. The stable pattern is what matters here: `core`, component packages, and non-Office renderers remain unchanged, while the Office preset / renderer can be replaced by the commercial engine. ## File Viewer vs conversion services [#file-viewer-vs-conversion-services] | Approach | Strengths | Limits | | ------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | Backend conversion | Can normalize files to PDF/images for caching, archival workflows, permission auditing, and unified fallback behavior | Requires conversion workers, queues, temporary files, fonts, caches, retries, and cleanup; private deployment can be costly | | Office Online / cloud services | High fidelity, low maintenance, mature collaboration features | Not always suitable for intranet, private deployment, sensitive files, offline environments, or strict compliance requirements | | File Viewer | Pure frontend, self-hostable, lazy-loaded, and easy to embed in business applications | Complex Office / CAD files still need real-file regression; not a replacement for professional editors or archival conversion | ## When File Viewer fits best [#when-file-viewer-fits-best] * Files should not be sent to a third-party conversion service. * The app runs in an intranet, private deployment, offline environment, or strict CSP setup. * One component needs to cover Office, PDF/OFD, CAD, archives, email, images, media, code, and structured data. * The product goal is preview, triage, search, print, export, and download rather than editing. * The frontend team wants renderer/preset composition instead of many unrelated viewer embeds. ## When backend conversion is better [#when-backend-conversion-is-better] * Long-term archival requires every file to become a stable PDF or image. * Very large files make browser memory or mobile performance the main constraint. * The workflow needs maximum fidelity, batch conversion, OCR, burned-in watermarks, audit records, or asynchronous review queues. * The team already runs a reliable LibreOffice, OnlyOffice, or commercial conversion service and can absorb the operational cost. ## Recommended mix [#recommended-mix] Many production systems can combine both approaches: * Use File Viewer for instant browser-side preview by default. * Trigger backend PDF conversion for archival, contracts, audit, or strict consistency cases. * Deploy File Viewer Worker, WASM, font, and vendor assets with the rest of the app's static resources. The Full/CDN payload includes binary `.ppt` under `vendor/ppt/`; use `options.presentation.pptModuleUrl` and matching asset URLs only for a non-standard route. * Collect real compatibility feedback through issues and sanitized samples instead of trusting synthetic files only. ## Validation checklist [#validation-checklist] * Try Word, Excel, PowerPoint, PDF, DWG, ZIP, and EML in the [demo](https://demo.file-viewer.app). * Validate the real formats your product cares about with sanitized files. * Check mobile WebView behavior, intranet static paths, Worker/WASM MIME types, CSP, and fonts. * For Office / CAD fidelity, review the [format fidelity notes](./format-fidelity). --- # Demo Guide (/guide/demo)
File Viewer by Flyfish v2.3.0 English demo showing DOCX, PPTX, DWG, interactive 3D STEP, and the file-capsule fusion

The current workspace starts with a real DOCX, reveals the file capsule when the top controls are engaged, then opens the sample library and switches renderer pipelines.

## Demo URLs [#demo-urls] * Main demo: [demo.file-viewer.app](https://demo.file-viewer.app) * iframe entry: [demo.file-viewer.app/iframe?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe?url=/example/en/calibre-demo.docx) * Document comparison: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html) * Official portal: [file-viewer.app](https://file-viewer.app) ## What To Check [#what-to-check] | Area | What to verify | | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Source controls | Open file, Paste link, and Samples each open their own anchored panel instead of sharing one generic dialog | | File capsule | The filename and correct format icon open the sample library; on desktop, the capsule separates on hover and flows back into the top bar one second after pointer leave | | Recent files | URL and sample history persists in local storage, each item can be removed, and the compact history control restores the panel | | Sample selector | Files are grouped by type, collapsible, icon-led, and the active file group stays discoverable in light and dark themes | | Toolbar | Search, fit, theme, download, print, HTML export, watermark, zoom, navigation, and format-specific actions appear only when supported | | Settings | More exposes the full option surface, including document-background mode, density, fit, watermark, archive, and current-format controls | | PDF | Page thumbnails, outline tree, floating toolbar, fit-to-width, search highlights, and side panel toggling | | Word | Stream-style document reading, correct text flow, printing without clipped first-page-only output | | Spreadsheet | Sheet tabs remain readable on desktop and mobile; optional column resize can be enabled | | Image | Open `multipage-ccitt-g4.tif` to verify two TIFF pages, group zoom/rotation/fit, page state, and double-click or keyboard lightbox access | | IFC | Open either buildingSMART IFC4 fixture to verify the local Web-IFC import worker, canvas, Fit, selection, and property panel without a runtime CDN | | Binary inspector | Open the raw, PE, ELF, Mach-O, ZIP, WASM, PNG, and Java-class samples to verify the explicit read-only structure tree and virtualized byte rows | | Archive | Nested entries preview through the same renderer registry, with safe metadata filtering, cache support, optional compact `ui.density:'compact'` spacing via `?density=compact`, and `archive.entryActions.download` checks for hiding nested entry downloads independently from the viewer-level original download | | Mobile | The filename stays centered, secondary controls collapse into one More action, only the document container scrolls, and heavy renderers remain lazy | ## Language-Aware Samples [#language-aware-samples] The demo follows the browser language by default. Chinese browsers open the Chinese sample system; other languages open the English sample system. Use `?locale=zh-CN` or `?locale=en-US` for a stable locale; the historical `lang` parameter remains compatible. The English demo uses public real-world samples for DOCX, PDF, PPTX, XLSX, and buildingSMART IFC4/IFC4.3, plus local lightweight fixtures for Markdown, text, logs, CSV, JSON, TypeScript, JavaScript, GeoJSON, glTF, binary inspection, and archive nesting. The Demo explicitly registers its optional IFC and binary renderers while keeping normal presets unchanged. All files and heavy Worker/WASM assets are served from the demo origin so enterprise intranet deployments do not depend on public CDNs at runtime.
File Viewer by Flyfish v2.3.0 English dark sample library with format-specific file icons

The sample library opens next to the active source, expands one group at a time, and uses coordinated dark-mode icon palettes instead of filtering light assets.

## Demo File Handoff Protocol [#demo-file-handoff-protocol] The main demo and iframe entry share the same file handoff protocol. Prefer `/iframe.html` for customer systems: an explicit `url` enters immersive mode, hiding brand, history, and source controls while retaining the document and the active format toolbar. Clean-URL static hosts can also use `/iframe`. Existing systems that already use `/index.html?from=...&name=...` continue to work with the same `postMessage(Blob)` flow. URL-based iframe: ```html ``` Blob handoff: ```html ``` `from` must match the parent origin. The demo accepts a `Blob` from that origin, wraps it as a `File` with `name`, and renders it. To keep an older main-demo integration, use `/file-viewer/index.html?from=...&name=...` with the same protocol. For customer delivery, use the GitHub Release asset `file-viewer-v2-*-official-demo-iframe.tar.gz`; it includes `iframe-example.html`, `README.iframe.md`, `iframe-manifest.json`, examples, and offline Worker/WASM/vendor assets. ## Local Demo [#local-demo] ```bash pnpm install pnpm dev ``` The Vite dev server serves the main demo. Open `/compare.html` on the same host to test side-by-side preview and the jsdiff-powered extracted-text view. DOCX and text files get aligned lines plus character-level additions and removals. PDF work is staged: it follows the PDF text layer, scanned PDFs need OCR, and an incomplete multi-page text layer stops instead of being presented as a complete diff. ## Production Smoke [#production-smoke] ### Reported-Issue Checks [#reported-issue-checks] Use the same uploaded bytes as the report, not just a similar sample. The regression suite covers hidden XLS search matches, DOC/DOCX text revisions, and page-relative DOCX cover borders on desktop and narrow screens. It also opens real files inside a resizable Element Plus drawer from cold-installed Vue CLI and React full tarballs, without aliases or application-specific Node polyfills. ```sh # Source-built Demo, including native file upload and HTML page/source switching. pnpm verify:closed-issue-regressions # Against the already-built Demo: CAD pixels/print and XLS main-thread/Worker paths. pnpm verify:issue-245-cad-output pnpm verify:issue-227-cfb pnpm verify:issue-204-resize pnpm verify:mobile-toolbar # Cold consumer of already-built package tarballs, with the browser assertions. PACKED_ISSUE_PACKAGE_DIR=/absolute/path/to/candidate-tarballs pnpm verify:issue-consumer # Actual mobile Safari taps in an already-booted Xcode iPhone Simulator. CLOSED_ISSUE_DEMO_URL=http://127.0.0.1:4179 pnpm verify:issue-243-ios ``` For HTML, open `page.html` from the sample library and switch between the styled static page and the original source. For DOC/DOCX revisions, use `docx.reviewMode: 'all'`, `'final'`, or `'original'`; this changes the preview, not the source file. A revised paragraph must show genuine deletion/insertion records, without marking unchanged copies of the same text. The sample library includes `word-revisions.doc` and `word-cover.docx`, copied byte-for-byte from the redistribution-approved reports. In **More > Settings > Formats > Word**, change **DOC / DOCX text revisions**, then apply. The text-format settings also expose the initial HTML view. No application-code edit is needed to compare the modes. `word-native-revisions.doc` and `word-native-revisions.docx` were created in Microsoft Word for Mac with Track Changes enabled. They cover company-name replacements, unchanged repeated text, mixed bold runs, tabs, soft line breaks, paragraph merges/splits, and table-cell replacements. In `final` mode, `Case join: JOINED` is one paragraph and the deleted soft break is gone. In `original` mode, the original two paragraphs return and the inserted split is removed. The regression fixtures include Word's separately saved Accept All and Reject All reference files and their SHA-256 hashes. These are synthetic samples, not the missing private attachment from #236; they do not claim coverage of all formatting, comment, move, or table-structure revisions. For OFD, open `ofd-resource-paths.ofd`. It combines a nested document, an alternate XML namespace prefix, and case differences in ZIP paths. Expect `Invoice resource reference` and a black square image. The regression suite also checks resource-XML directories, `BaseLoc`, parent paths, URI encoding, resource priority, and missing nonessential resources. Missing images or font catalogs must not discard readable text; missing required pages, malformed XML, and invalid JBIG2 must finish loading with an error, not a blank success. This constructed sample is not the unavailable original from #57. For CAD, open `drawing.dxf`, `samples/apache/blocks_and_tables.dwf`, or `samples/autodesk/house.dwfx`. Compare dark-background source mode with black-on-white monochrome, download PNG/JPEG from the CAD toolbar, export HTML, and print to PDF. Check the output pixels, not just the mode label. Output captures the current view/current DWF page; select Fit before exporting the full drawing. Image downloads retain configured text/image watermarks and respect download/export permissions; an unreadable watermark fails explicitly instead of producing an unmarked image. In a phone-sized host or narrow dialog, the native component toolbar keeps a compact row with Search, zoom and More. Search opens a separate panel; More reveals output actions. Controls must not overlap at 320px or 390px, and a narrow desktop dialog must use its own width rather than the browser width. Wide hosts keep the inline search field. On iPhone, enter a search, close the keyboard, and tap Next again: the host must not stay scrolled beneath Safari's status area. The boot skeleton must not impose `100vh` minimums on the mounted application. Recent history stays collapsed until requested, so it does not cover worksheet tabs. The column-resize check uses real pointer dragging, switches sheets, zooms in/out, and disables resizing through Demo settings; a changed cursor alone is not a pass. The MiniFAT check uses a synthetic legacy XLS with an unused invalid MiniFAT pointer, then exercises main-thread and actual Worker parsing through file upload and last-row search. It is not the private #227 attachment. Do not mark that original report verified until the same file is tested privately; damaged required streams must fail clearly rather than silently dropping cells. After deployment, repeat the Demo checks against `https://demo.file-viewer.app` using `CLOSED_ISSUE_DEMO_URL`. Check `build-info.json` for the expected clean source commit. On iPhone, verify that the visible PDF content moves on Next/Previous and the controls remain reachable; a changed page counter alone is not a pass. Local results and an npm upload are not evidence that the production Demo has been updated. The repository keeps browser smoke scripts for the demo and component packages: ```bash pnpm verify:demo-browser-smoke pnpm verify:demo-sample-click-regression pnpm verify:component-browser-smoke pnpm verify:browser-smoke ``` Use these checks before publishing a release that touches renderers, assets, toolbar behavior, search, print, or sample files. --- # Local Development (/guide/development) ## Install [#install] ```bash pnpm install ``` ## Common Commands [#common-commands] | Command | Purpose | | ----------------------------- | -------------------------------------------------------------------------------------------------------- | | `pnpm dev` | Run the main demo | | `pnpm docs:dev` | Run the documentation site | | `pnpm site:dev` | Run the official site | | `pnpm build-only` | Build the main demo | | `pnpm docs:build` | Build documentation | | `pnpm site:build` | Build the official site | | `pnpm verify:format-support` | Verify 274 registered extensions (224 stable, 50 experimental) and 47 renderer pipelines stay documented | | `pnpm verify:renderer-assets` | Verify runtime assets are included in renderer packages and web builds | | `pnpm verify:browser-smoke` | Run demo and component browser smoke tests | ## Release Gate [#release-gate] Before publishing packages or deploying production, run the focused checks for the area you changed. Renderer and asset changes should at least pass: ```bash pnpm build-only pnpm docs:build pnpm verify:format-support pnpm verify:renderer-assets pnpm verify:smoke-matrix pnpm verify:npm-install-smoke ``` Use `pnpm verify:migration-gates` for a broader migration gate. ## Batch Release Safety [#batch-release-safety] The private maintainer checkout builds and freezes the package artifacts once. Local packing uses four workers by default (`FILE_VIEWER_PACK_CONCURRENCY`); registry download and comparison use four (`FILE_VIEWER_REGISTRY_CONCURRENCY`). Both accept 1–8 workers. Reusing an already-built artifact is only valid when its source and dependency inputs are unchanged; it does not replace the frozen-release checks. The GitHub npm workflow publishes the immutable Release tarballs with trusted publishing. It checks all package identities and integrity hashes before the first upload, then publishes in dependency layers, with up to three uploads and six registry checks at a time. A layer must become visible with matching integrity before dependent packages can start. Failures stop new work and wait for active operations to finish; rerunning the same Release skips only versions whose bytes already match. An authorization failure or registry delay is not a reason to allocate another version. Compatibility aliases need their own version bump when their exact dependency changes. In particular, reusing an old `msdoc-viewer` version would keep those users on its old DOC renderer even after the other packages are updated. The version-freeze check rejects that plan. Registry verification, cold installs, production Demo checks and the final release postcheck are still required after publishing. --- # Distribution (/guide/distribution) ## npm Registry [#npm-registry] Common installs: ```bash npm install @file-viewer/vue3 @file-viewer/preset-office # Heavy users / all-format attachment centers: npm install @file-viewer/vue3-full # Replace @file-viewer/vue3 with @file-viewer/web / react / vue2.7 / vue2.6 / jquery / svelte for other stacks. ``` Every ecosystem has a matching `*-full` package. Full packages already include `preset-all` and their version-aligned renderer/Worker/WASM/font/vendor payload; do not install or pass another preset. Vite or the included CLI publishes those assets under `/file-viewer/`, including the verified binary-PPT 0.3.4 runtime under `vendor/ppt/`. Pass the preset through `options.preset` in Webpack, Rspack, Rollup, Umi, classic multi-page apps, or internal component libraries. Vite projects can additionally install and register the plugin: ```bash npm install -D @file-viewer/vite-plugin ``` Recommended Vite setup: ```ts fileViewerRenderers({ copyAssets: true }) ``` After registration, the plugin recognizes installed full / `@file-viewer/preset-*` packages, injects the capability layer, and publishes complete full-package assets under `/file-viewer/`. Use single renderer packages plus `formats` only for strict custom cuts. Common customization boundaries: | Option | Purpose | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `copyAssets:true` | Recognizes full packages / presets; full packages publish under `/file-viewer/` in dev and production, while standard packages/presets keep root placement; required for full packages | | `formats` / `renderers` | Generates exact renderer imports when you do not use a preset, or when a preset needs a few extra formats | | `scan:true` | Reads source hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes | | `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-activation enabled while `scan:true` is active | | `inject:false` | Disables auto injection so application code can import `virtual:file-viewer-renderers` and pass `options.renderers` manually | Registry links: * [`@file-viewer/core`](https://www.npmjs.com/package/@file-viewer/core) * [`@file-viewer/web`](https://www.npmjs.com/package/@file-viewer/web) * [`@file-viewer/vue3`](https://www.npmjs.com/package/@file-viewer/vue3) * [`@file-viewer/react`](https://www.npmjs.com/package/@file-viewer/react) * [`@file-viewer/svelte`](https://www.npmjs.com/package/@file-viewer/svelte) * [`@file-viewer/renderer-word`](https://www.npmjs.com/package/@file-viewer/renderer-word) * [`@file-viewer/renderer-presentation`](https://www.npmjs.com/package/@file-viewer/renderer-presentation) * [`@file-viewer/ppt@0.3.4`](https://www.npmjs.com/package/@file-viewer/ppt) * [`@file-viewer/pptx`](https://www.npmjs.com/package/@file-viewer/pptx) * [`@file-viewer/preset-lite`](https://www.npmjs.com/package/@file-viewer/preset-lite) * [`@file-viewer/preset-office`](https://www.npmjs.com/package/@file-viewer/preset-office) * [`@file-viewer/preset-engineering`](https://www.npmjs.com/package/@file-viewer/preset-engineering) * [`@file-viewer/preset-all`](https://www.npmjs.com/package/@file-viewer/preset-all) * [`@file-viewer/vite-plugin`](https://www.npmjs.com/package/@file-viewer/vite-plugin) File Viewer package metadata points to the public repositories, documentation, issue trackers, Apache-2.0 license, and npm donation URL: [dev.flyfish.group/donate?source=npm](https://dev.flyfish.group/donate?source=npm). The bundled `@file-viewer/ppt` runtime and other dependencies retain their included licenses. `@file-viewer/core` stays lightweight and does not install Word or presentation engines directly. Use `@file-viewer/preset-lite`, `@file-viewer/preset-office`, or `@file-viewer/preset-engineering` for product-shaped bundles; use individual renderer packages for the smallest custom install, or `@file-viewer/preset-all` when you want the same full renderer matrix as the official demo. Presentation routing keeps two standalone engines: PowerPoint 97–2003 `.ppt` uses the Worker/OffscreenCanvas/WASM `@file-viewer/ppt@0.3.4` package, while PPTX/OpenXML uses `@file-viewer/pptx` and its separate Worker. Normal ESM/Vite builds resolve the npm dependency directly. Demo, Full, copy-assets, and CDN/IIFE distributions ship the matching public runtime as one integrity-checked `vendor/ppt/` directory, so `.ppt` works without URL configuration. `pptModuleUrl`, `pptWorkerUrl`, `pptWasmUrl`, and `pptFontUrl` are advanced overrides for custom asset routing. `@file-viewer/ppt` keeps its own included license; the public runtime keeps its visible watermark, and removing that PPT watermark requires commercial authorization. ## GitHub [#github] Main repository: * [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer) Suggested discovery topics for the main repository: ```txt file-viewer, document-viewer, document-preview, file-preview, office-viewer, pdf-viewer, docx, pptx, xlsx, cad-viewer, drawio, excalidraw, web-component, vue, react, svelte, typescript, wasm, offline-first, self-hosted ``` When you are ready to update the repository topics: ```bash gh repo edit flyfish-dev/file-viewer \ --remove-topic cad \ --remove-topic office \ --remove-topic jquery \ --remove-topic ofd \ --add-topic document-preview \ --add-topic file-preview \ --add-topic web-component \ --add-topic self-hosted ``` GitHub currently allows up to 20 repository topics, so treat this list as the main SEO surface. ## Release Downloads [#release-downloads] GitHub Releases can carry: * static demo builds * docs builds * npm tarballs for offline installs * component demo builds * source bundles * demo GIF or MP4 assets for posts and README embeds For offline or intranet package installs, download the tarballs and install them through a private registry or direct local paths. The public GitHub repository keeps source, small release metadata, and lightweight package output in git. Full demo, component demo, docs, and sample-file builds should live in GitHub Releases or Cloudflare Pages deployments instead of expanded top-level directories, so a normal clone stays practical. Use `pnpm release:public -- --expanded-assets` only for one-off delivery or mirror troubleshooting that truly needs expanded static assets. ## Official Demo iframe Artifact [#official-demo-iframe-artifact] When a customer asks for the official demo build output for iframe integration, use the GitHub Release asset `file-viewer-v2-*-official-demo-iframe.tar.gz`. It does not require installing npm packages in the host application. Extract the whole archive to one static directory and keep `assets/`, `vendor/`, `wasm/`, and `example/` together. `/iframe.html` is the recommended chrome-free entry, and clean-URL static hosts can also use `/iframe`. `/index.html` keeps the original full demo and remains compatible with the same `url`, `from`, `name`, and `postMessage(Blob)` protocol. URL-based iframe: ```html ``` Blob handoff from the parent page: ```html ``` `from` must match the parent origin. The demo accepts only a `Blob` from that origin and renders it as the provided `name`. The archive also includes `iframe-example.html`, `README.iframe.md`, and `iframe-manifest.json`; `pnpm release:demo-iframe:pack` and `pnpm verify:demo-iframe-artifact` make this artifact part of the standard release flow. ## Full-Package Runtime Assets [#full-package-runtime-assets] Full packages carry the renderer matrix and its same-version File Viewer-owned runtime assets. In non-Vite projects, publish that included payload with the Full package CLI: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` This copies and verifies Worker, WASM, PDF, CAD, Typst WASM/fonts, SQLite, Archive, binary-PPT 0.3.4, PPTX, Draw\.io, and other renderer assets and writes `flyfish-viewer-assets.json`. Serve the directory from `/file-viewer/`. Every full package uses `file-viewer/` under the deployment base by default (`/file-viewer/` at the origin root) and automatically points to the PDF.js, DOCX, binary-PPT, PPTX Worker, spreadsheet, CAD, Typst, Draw\.io, SQLite, and Archive assets there. If assets live elsewhere, call `setDefaultFullAssetBaseUrl('/your-prefix/')` during startup; explicit `options.*Url` values keep the highest priority. Direct CDN `web-full`, or an intact deployment of its complete `dist/`, resolves all packaged assets relative to the script URL. For Cloudflare Pages, edge compression is enabled according to the visitor `Accept-Encoding` header. `scripts/deploy-cloudflare-pages.mjs` also Brotli-compresses oversized WASM files before Direct Upload and writes `Content-Encoding: br`, `Vary: Accept-Encoding`, `Content-Type: application/wasm`, and long-term cache headers into `_headers`. This keeps large assets such as the Typst compiler WASM deployable under the original `.wasm` URL. After deployment, verify the live headers with: ```bash pnpm verify:cloudflare-compression ``` ## Sponsorship [#sponsorship] File Viewer-authored source and packages produced by this repository remain Apache-2.0 open source; the bundled `@file-viewer/ppt` runtime retains its independent LICENSE and NOTICE, while other dependencies retain their included licenses. Sponsorship helps fund compatibility work, documentation, examples, offline assets, and long-term maintenance: * [GitHub Sponsors](https://github.com/sponsors/wybaby168) for one-time or recurring contributions * [WeChat / Alipay](https://dev.flyfish.group/sponsor?source=github) for convenient domestic one-time support * [Enterprise support](https://dev.flyfish.group/shop) for private deployment, custom compatibility work, and committed response expectations Sponsorship does not change access to open-source features and does not include a service-level agreement unless a published tier explicitly says otherwise. --- # Docker Deployment (/guide/docker) The Docker image serves the static demo build through nginx. It includes the main viewer at `/`, the zero-dependency iframe entry at `/iframe.html`, and the comparison demo at `/compare.html`. ## Run From Docker Hub [#run-from-docker-hub] ```bash docker run -d \ --name file-viewer \ -p 8080:80 \ flyfishdev/file-viewer:latest ``` Open: * Main viewer: `http://localhost:8080/` * iframe embed: `http://localhost:8080/iframe.html?url=/example/word.docx` * Comparison demo: `http://localhost:8080/compare.html` * Health check: `http://localhost:8080/healthz` ## Build Locally [#build-locally] ```bash pnpm docker:build docker run --rm -p 8080:80 flyfishdev/file-viewer:latest ``` ## Multi-arch Publish [#multi-arch-publish] ```bash docker login DOCKER_IMAGE=flyfishdev/file-viewer pnpm docker:publish ``` The Docker flow targets `linux/amd64` and `linux/arm64`. ## Offline Notes [#offline-notes] The image serves static demo assets from itself, including offline Worker, WASM, vendor, and example files. Keep `/iframe.html`, `/assets/*`, `/vendor/*`, and `/example/*` on the same static origin when putting another reverse proxy in front of the container. For native component integrations, still copy viewer runtime assets into your own product deployment with: ```bash npx --yes file-viewer-copy-assets ./public/file-viewer ``` --- # Ecosystem Packages (/guide/ecosystem) ## Recommended Packages [#recommended-packages] Standard component packages are intentionally light. Installing `@file-viewer/vue3`, `@file-viewer/react`, `@file-viewer/web`, `@file-viewer/svelte`, `@file-viewer/jquery`, or a Vue 2 package gives you the native ecosystem component, types, controller APIs, and the core foundation. Real format coverage is assembled by presets or individual renderer packages. | Strategy | Install | Notes | | ------------------------ | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | | Lightest component entry | `npm i @file-viewer/vue3` | Add format capability only after the component shell is wired | | Lightweight attachments | `npm i @file-viewer/vue3 @file-viewer/preset-lite` | Text, Markdown, code, image, audio, video; pass the preset through `options.preset` | | Office document platform | `npm i @file-viewer/vue3 @file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, OpenDocument; recommended default for document apps | | Engineering platform | `npm i @file-viewer/vue3 @file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, EDA | | Full demo capability | `npm i @file-viewer/vue3 @file-viewer/preset-all` | One-step full capability for demos, admin tools, and internal all-format workbenches | | Full package | `npm i @file-viewer/vue3-full` | Enables `preset-all` by default, no manual `options.preset` needed | | CDN full trial | `https://unpkg.com/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js` | Script-tag validation with lazy renderers and packaged binary-PPT 0.3.4 assets | | Strict custom cut | `npm i @file-viewer/vue3 @file-viewer/renderer-pdf` | Install one renderer and pass it through `options.renderers` | ## Full Package Asset Contract [#full-package-asset-contract] Since `2.1.30`, all eight Full packages share one delivery contract. They include and enable `preset-all` together with version-aligned renderer, Worker, WASM, font, Draw\.io, SQLite, and other vendor assets; Vite or the included CLI publishes that payload on the application's own origin. The current layout includes both the integrity-checked binary `.ppt` 0.3.4 runtime and the lazy local EPUB engine with its NOTICE, so neither path needs a runtime CDN. | Build path | Complete deployment | | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Vite | Register `fileViewerRenderers({ copyAssets:true })`; the plugin recognizes the installed Full package and serves/copies all assets in both dev and build | | Webpack, Vue CLI, Rspack, Rollup, Umi, other bundlers | Run `npx --no-install file-viewer-copy-assets ./public/file-viewer`; the binary is included by the Full package at the same version | | Script tag / CDN | Use jsDelivr/unpkg directly or deploy the complete `@file-viewer/web-full/dist/` directory; no copy command is required | Do not install another `preset-all` or a separately versioned asset copier next to a Full package. All Full packages default to `file-viewer/` under the deployment base; use `setDefaultFullAssetBaseUrl('/your-prefix/')` only when your static directory differs. `options.preset` is the bundler-neutral assembly path. Webpack, Rspack, Rollup, Umi, classic multi-page apps, micro-frontends, and internal component libraries can import a preset explicitly and pass it to the component: ```ts import officePreset from '@file-viewer/preset-office' const viewerOptions = { preset: officePreset, rendererMode: 'replace' } ``` Vite projects can additionally install `@file-viewer/vite-plugin` to remove manual imports. Vite plugins still need to be registered once in `vite.config.ts`; after that, `fileViewerRenderers()` or `fileViewerRenderers({ copyAssets:true })` auto-discovers installed `@file-viewer/preset-*` packages and injects the generated virtual module into Vite HTML entrypoints. Components keep `autoRenderers:true` by default, so Vue, React, Svelte, jQuery, and Vanilla JavaScript / Pure Web receive the matching preview capability automatically. `preset-all` is intentionally complete and therefore heavier; production apps should normally prefer `preset-lite`, `preset-office`, `preset-engineering`, or individual renderers. ```ts // vite.config.ts import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default { plugins: [ fileViewerRenderers({ copyAssets: true // Installed presets are activated automatically; no hand-written import or renderers prop. }) ] } ``` | Stack | Standard package | Notes | | ------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | Core foundation | `@file-viewer/core` | Framework-neutral contracts, browser engine, renderer registry, events, search, zoom, print, export, and asset manifests | | Binary PPT runtime | `@file-viewer/ppt@0.3.4` | Independently versioned dependency; Full/CDN ships its public `vendor/ppt/` assets, isolated from the PPTX Worker path | | PPTX engine | `@file-viewer/pptx` | OpenXML presentation parsing with progressive Worker output | | Word renderer | `@file-viewer/renderer-word` | DOCX/DOC/RTF/ODT renderer plugin that lazy-loads Word engines outside core | | Lite renderer preset | `@file-viewer/preset-lite` | Text, Markdown, code, image, audio, and video preview lines | | Office renderer preset | `@file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, and OpenDocument preview lines | | Engineering renderer preset | `@file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, and EDA preview lines | | Full renderer preset | `@file-viewer/preset-all` | Registers the full lazy renderer set | | Vite on-demand plugin | `@file-viewer/vite-plugin` | Generates renderer imports from explicit formats or source hints | | Web Component / Vanilla JS | `@file-viewer/web` | ``, `mountViewer`, IIFE bundle, and asset copy CLI | | Web Component / Vanilla JS Full | `@file-viewer/web-full` | Complete-matrix Custom Element, IIFE, and imperative mount for script tags and POCs | | Vue 3 | `@file-viewer/vue3` | Native Vue 3 plugin and component | | Vue 3 Full | `@file-viewer/vue3-full` | Complete-matrix Vue 3 package with the same component API | | Vue 2.7 | `@file-viewer/vue2.7` | Native Vue 2.7 component | | Vue 2.7 Full | `@file-viewer/vue2.7-full` | Complete-matrix package for modern Vue 2 applications | | Vue 2.6 | `@file-viewer/vue2.6` | Dedicated Vue 2.6 compatibility line | | Vue 2.6 Full | `@file-viewer/vue2.6-full` | Complete-matrix package for legacy Vue 2.6 applications | | React 18/19 | `@file-viewer/react` | Native React component and handle APIs | | React 18/19 Full | `@file-viewer/react-full` | Complete-matrix React package with the same component and hook APIs | | React 16.8/17 | `@file-viewer/react-legacy` | Legacy React package with the same viewer semantics | | React 16.8/17 Full | `@file-viewer/react-legacy-full` | Complete-matrix package for old React applications | | jQuery | `@file-viewer/jquery` | Traditional admin-system integration | | jQuery Full | `@file-viewer/jquery-full` | Complete-matrix package for classic admin systems | | Svelte | `@file-viewer/svelte` | Svelte component and action | | Svelte Full | `@file-viewer/svelte-full` | Complete-matrix Svelte package with the same component and action APIs | ## Renderer Packages [#renderer-packages] Heavy renderers are split so applications can install only what they need: * `@file-viewer/renderer-pdf` * `@file-viewer/renderer-word` * `@file-viewer/renderer-ofd` * `@file-viewer/renderer-presentation` * `@file-viewer/renderer-cad` * `@file-viewer/renderer-typst` * `@file-viewer/renderer-archive` * `@file-viewer/renderer-email` * `@file-viewer/renderer-epub` * `@file-viewer/renderer-text` * `@file-viewer/renderer-image` * `@file-viewer/renderer-media` * `@file-viewer/renderer-mindmap` * `@file-viewer/renderer-geo` * `@file-viewer/renderer-drawing` * `@file-viewer/renderer-3d` * `@file-viewer/renderer-data` * `@file-viewer/renderer-eda` Standard component packages depend on the lightweight core foundation by default. Install only the renderer packages your product needs, use `@file-viewer/preset-lite` / `@file-viewer/preset-office` / `@file-viewer/preset-engineering` for product-shaped bundles, or pass `@file-viewer/preset-all` when you want the complete official demo capability matrix. For example, PowerPoint preview is provided by `@file-viewer/renderer-presentation`, which routes binary `.ppt` to the native-WASM `@file-viewer/ppt@0.3.4` engine and PPTX/PPTM/POTX/POTM/PPSX/PPSM to the separate `@file-viewer/pptx` Worker engine. Neither engine enters the core-only install. Style isolation is controlled by the shared `options.styleIsolation` field. Every standard component defaults to Shadow DOM so host global CSS cannot break the viewer. Customize with `--file-viewer-*` tokens plus `::part()`; use `styleIsolation:'none'` only as a legacy light-DOM escape hatch. See [Style Isolation And Customization](/guide/style-isolation). ## Vite Auto Assembly [#vite-auto-assembly] Use the Vite plugin when your app wants a complete developer experience without hand-writing every renderer import. The default setup auto-discovers installed presets; explicit `formats` and `scan:true` are only needed for strict custom cuts or source-hint driven assembly: ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true, chunkStrategy: 'renderer' }) ] }) ``` With `scan: true`, use `preset:'auto'` or `autoPresets:true` when installed presets should remain active while source hints add extra renderers. The scan reads hints such as `fileViewerFormats = ['pdf', 'docx']`, `data-file-viewer-formats="dwg,xmind"`, and upload `accept=".pdf,.xlsx"`. ## 2.1.0 Modular Import Paths [#210-modular-import-paths] ### Minimal import: install exactly the renderer you need [#minimal-import-install-exactly-the-renderer-you-need] For a PDF-only product: ```bash npm i @file-viewer/vue3 @file-viewer/renderer-pdf ``` ```ts import { pdfRenderer } from '@file-viewer/renderer-pdf' const options = { rendererMode: 'replace', renderers: [pdfRenderer] } ``` Replace `@file-viewer/vue3` with `@file-viewer/web`, `@file-viewer/react`, `@file-viewer/svelte`, `@file-viewer/jquery`, `@file-viewer/vue2.7`, or `@file-viewer/vue2.6` for other stacks. The `options` contract remains the same. ### Composed import: choose a product-shaped preset [#composed-import-choose-a-product-shaped-preset] For an Office document platform: ```bash npm i @file-viewer/vue3 @file-viewer/preset-office ``` ```ts import officePreset from '@file-viewer/preset-office' const options = { rendererMode: 'replace', preset: officePreset } ``` Use `preset-lite` for lightweight attachments, `preset-engineering` for CAD / 3D / Typst / EDA / data assets, and `preset-all` for the full sample matrix or all-format admin workbenches. Add `preset:'auto'` or `autoPresets:true` when you also enable `scan:true`, so installed presets and source hints work together. `copyAssets:true` copies Worker, WASM, PDF fonts, CAD, Typst WASM/fonts, Archive, and Data assets into your deployment directory so private intranet deployments do not depend on public CDNs. ## React Legacy [#react-legacy] React 16.8 and 17 projects use `@file-viewer/react-legacy` or `@file-viewer/react-legacy-full`. They keep the same props, controller, event, renderer, and preset contracts as the current React packages while avoiding a React 18 runtime requirement. See the [React integration guide](/guide/quickstart-react) for the shared API and migration boundary. ## jQuery [#jquery] Use `@file-viewer/jquery` when a traditional admin system or legacy page already standardizes on jQuery-style plugins: ```bash npm install @file-viewer/jquery ``` The package exposes a native jQuery integration over the same core options, events, operation guards, search, zoom, print, export, and renderer presets. It does not embed Vue or React. Use `@file-viewer/jquery-full` for the complete matrix without importing a preset. Vite still uses `copyAssets:true`; non-Vite jQuery builds run the Full package's included `npx --no-install file-viewer-copy-assets ./public/file-viewer` command. ## Svelte [#svelte] Use `@file-viewer/svelte` for Svelte applications: ```bash npm install @file-viewer/svelte ``` The Svelte package keeps framework-native props and events while delegating renderer work to `@file-viewer/core` and the selected renderer packages. Use `@file-viewer/svelte-full` for the complete matrix without importing a preset. SvelteKit/Vite uses `copyAssets:true`; other builds run the Full package's included `npx --no-install file-viewer-copy-assets ./public/file-viewer` command. ## Core API [#core-api] Use `@file-viewer/core` when building a custom host or a new ecosystem package: ```bash npm install @file-viewer/core ``` Core is pure TypeScript and owns shared contracts, file source normalization, renderer registration, lifecycle events, operation availability, asset manifests, search/zoom/print/export protocols, and utility APIs. UI-specific behavior belongs in the component package for each framework. ## PPT and PPTX Engines [#ppt-and-pptx-engines] PowerPoint rendering is available through `@file-viewer/renderer-presentation`. Its lower-level engines keep binary and OpenXML formats separate: ```bash npm install @file-viewer/ppt@0.3.4 @file-viewer/pptx ``` Use `@file-viewer/ppt` only for PowerPoint 97–2003 `.ppt`, and `@file-viewer/pptx` only for PPTX/OpenXML presentations. Most application teams should use the presentation renderer or `preset-office` instead of calling either engine directly. ## Compatibility Names [#compatibility-names] | Historical package | Prefer now | | ---------------------------------- | --------------------- | | `@flyfish-group/file-viewer-web` | `@file-viewer/web` | | `@flyfish-group/file-viewer3` | `@file-viewer/vue3` | | `file-viewer3` | `@file-viewer/vue3` | | `@flyfish-group/file-viewer` | `@file-viewer/vue2.7` | | `@flyfish-group/file-viewer-react` | `@file-viewer/react` | Compatibility packages keep old projects working, but new projects get clearer package names, better npm discoverability, and a cleaner upgrade path with the standard names. --- # FAQ (/guide/faq) ## The viewer is blank [#the-viewer-is-blank] Confirm the host container has a stable height and the file has a recognizable extension or explicit `type`. ## Does a Full package require a manual asset copy? [#does-a-full-package-require-a-manual-asset-copy] Not with Vite, and not when the complete `web-full/dist/` directory is deployed. Full packages include `preset-all`, but complete format support also requires their matching Worker, WASM, font, and vendor files to be published. Version `2.1.30` gives every Full package one supported delivery path: * Vite: enable `fileViewerRenderers({ copyAssets: true })`; dev and build publish matching full-package assets under `/file-viewer/`. * Webpack, Vue CLI, and other tools: run the same-version binary included by the full package: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` * Custom static prefix: call the full package's `setDefaultFullAssetBaseUrl()` during startup. * CDN/IIFE: deploying the complete `@file-viewer/web-full/dist/` directory needs no extra copy. An entry-only build can run the included CLI. Do not install another `preset-all` or asset copier version beside a full package. Then confirm your server returns the correct MIME type for `.wasm`, `.js`, fonts, and JSON manifests. Strict CSP deployments should serve all viewer assets from the same trusted origin. If a Worker or WASM still fails, inspect its URL: the response must be the real asset, not an SPA HTML fallback with status 200. ## How can I verify the DOCX 0.3.31 fixes are active? [#how-can-i-verify-the-docx-0331-fixes-are-active] The current Word renderer uses `@file-viewer/docx@0.3.35` in both the main thread and the offline Worker. It includes the Japanese text, VML text box, Apache POI `w:hMerge`, multi-section floating-shape, complex frame, section, positioned-page, revision, paragraph-mark, and soft-break fixes, and blocks external document resources by default. After upgrading, redeploy the matching viewer assets and confirm the browser requests `vendor/docx/docx.worker.js?file-viewer-docx=0.3.35` (possibly below your `file-viewer/` base) as JavaScript. Do not reuse a Worker from an older package version. If the old layout remains, purge the CDN or service-worker cache and reload the document. ## Why does a full package still say the libarchive Worker did not load? [#why-does-a-full-package-still-say-the-libarchive-worker-did-not-load] Every full package points Archive, PDF, DOCX, Excel, PPTX, CAD, Typst, Draw\.io, SQLite, and related offline assets to `file-viewer/` under the deployment base by default. For a root deployment, confirm these example URLs return the real JavaScript/WASM files instead of a 404 page or an SPA HTML fallback: * `/file-viewer/vendor/libarchive/worker-bundle.js` * `/file-viewer/vendor/libarchive/libarchive.wasm` If assets do not live at `file-viewer/` under the deployment base, set their location once during startup: ```ts import { setDefaultFullAssetBaseUrl } from '@file-viewer/react-full' setDefaultFullAssetBaseUrl('/your-static-prefix/') ``` The compatibility-mode notice does not mean ZIP/TAR/GZIP are unusable. It means the libarchive Worker could not start, so RAR, 7z, encrypted archives, and other libarchive-only formats still need the Worker/WASM assets. ZIP, TAR, and GZIP continue through the compatibility path, and legacy GBK/GB18030 Chinese ZIP entry names stay readable there. ## npm 11 fails with `Cannot read properties of null (reading 'matches')` [#npm-11-fails-with-cannot-read-properties-of-null-reading-matches] This is usually not a `@file-viewer/*` version mismatch. We verify npm 11.17.0 against a clean registry install and a local tgz dependency-closure install for `@file-viewer/vue3 + @file-viewer/preset-office`. The message is an npm Arborist crash while building the dependency tree. The most common trigger is a project directory whose `node_modules` was created by pnpm, bun, vlt, or another package manager, followed by `npm install` in the same directory. npm may hit a store-style symlink with a null target and throw this internal `matches` TypeError. Use one package manager per project and reset the install directory: ```bash # If the project uses npm rm -rf node_modules package-lock.json npm-shrinkwrap.json npm cache verify npm install ``` ```bash # If the project uses pnpm, keep using pnpm rm -rf node_modules package-lock.json pnpm install ``` For offline tgz installs, the top-level tgz still needs all runtime dependencies to resolve from npm, a private registry, or sibling local tarballs. In intranet environments, publish the same-version `@file-viewer/vue3`, the selected preset, its renderer packages, and `@file-viewer/core` to a private registry, or declare the local tgz dependency closure together. Release verification includes: ```bash pnpm verify:npm-install-smoke ``` ## Can I deploy without public CDNs? [#can-i-deploy-without-public-cdns] Yes. Runtime assets are designed to be self-hosted. Full packages publish Draw\.io, Typst, CAD, Archive, PDF, DOCX, Spreadsheet, SQLite, and other heavy assets through the Vite plugin or their included same-version `file-viewer-copy-assets` binary; `web-full` can instead deploy its complete `dist/`. ## Why does every format not expose every toolbar action? [#why-does-every-format-not-expose-every-toolbar-action] Each renderer reports operation availability. Download is usually available, but print, HTML export, search, zoom, page navigation, and text anchors depend on the active renderer. ## Should I use an iframe? [#should-i-use-an-iframe] No for standard package integrations. Use the native package for your stack. iframe-style demos can still be useful for embedding the full hosted demo, but the core product path is native and debuggable. --- # Format Fidelity (/guide/format-fidelity) ## High-confidence Preview Lines [#high-confidence-preview-lines] * PDF, OFD, images, audio, video, Markdown, source code, text, JSON/YAML/TOML/XML/SQL, archives, email, EPUB, Mermaid, Excalidraw, draw\.io, and common Office/OpenDocument files. * CAD preview is powered by `@flyfish-dev/cad-viewer` through `@file-viewer/renderer-cad`; DWG, DXF, DWF, and DWFx assets stay self-hostable. * STEP / STP, IGES / IGS, and BREP preview uses a self-hosted OCCT worker, runtime, and WASM module to build renderable meshes locally, with orbit controls, fit-to-view, and unified zoom. * Word preview uses `@file-viewer/renderer-word` and the self-maintained `@file-viewer/docx` path for readable stream-style DOCX rendering. * Presentation preview uses `@file-viewer/renderer-presentation` with two isolated native engines: PowerPoint 97–2003 `.ppt` lazy-loads the independently versioned native-WASM `@file-viewer/ppt@0.3.4` runtime, while PPTX/OpenXML lazy-loads `@file-viewer/pptx` and its Worker. Full and CDN/IIFE distributions ship both routes' matching assets; `@file-viewer/ppt` keeps its included license and visible public watermark. ## Structure-first Lines [#structure-first-lines] Some engineering formats are intentionally conservative: | Format family | Current behavior | | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | OLB / DRA | Safe structure preview for common OrCAD / Allegro containers and readable metadata | | OAS / OASIS | Readable fixtures render; complex binary OASIS stays structure-index focused until the dedicated layout kernel matures | | IFC | Optional experimental local visual preview through `@file-viewer/renderer-3d/ifc`, with self-hosted That Open / `web-ifc` assets, fit, selection and property inspection; the official Demo includes IFC4 and IFC4.3 fixtures | | Streaming Geo3D | Explicit experimental `@file-viewer/renderer-3d/geo3d` path for LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles and 3TZ. COPC/COG/3D Tiles preserve progressive/range access; TIFF is metadata-sniffed before takeover; 3TZ extraction applies traversal/size/count/duplicate guards. Self-host the decoder assets and validate production dataset sizes; converting LAS/LAZ to COPC and GeoTIFF to COG can improve streaming. | | 3DM | Signature detection and integration guidance; a dedicated `rhino3dm` renderer is still required for visual preview | | PlantUML | Offline source/SVG-style preview by default; configure an intranet PlantUML service for full server-rendered SVG | ## Verification [#verification] Use the built-in checks when the format matrix changes: ```bash pnpm verify:format-support pnpm verify:smoke-matrix pnpm verify:renderer-assets ``` --- # Supported Formats (/guide/formats)
File Viewer by Flyfish v2.3.0 English format sample library with grouped filenames and format-specific icons

The demo groups representative samples for all 47 preview pipelines. Stable rows require redistributable real-file fixtures and browser assertions; synthetic or renamed fixtures never count as evidence. Experimental rows keep their limits visible.

## Main Preview Pipelines [#main-preview-pipelines] | Category | Examples | | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Word | `docx`, `docm`, `dotx`, `dotm`, legacy `doc`, `dot`, RTF/ODT; structured stable `wpd`, `wp`, `wp5`, `wp6`, `hwp`, `hwpx` | | Spreadsheets | `xlsx`, `xlsm`, `xlsb`, `xls`, `xla`, `xlam`, `csv`, `tsv`, `ods`, `fods`, `dbf`; stable high-fidelity `numbers` | | Presentations | binary `ppt`, `pot`; OpenXML `pptx`, `pptm`, `potx`, `potm`, `ppsx`, `ppsm`; OpenDocument `odp`; stable high-fidelity `key` | | Apple documents | stable high-fidelity `pages`, `numbers`, and `key` with iWork '09 XML/APXL and modern Snappy/IWA parser paths | | Layout documents | `pdf`, `ofd`, `typ`, `typst` | | Archives | `zip`, `7z`, `rar`, `tar`, `gz`, `tgz`, `cab`, `iso`, `apk`, `cbz`, `cbr`, and more | | Email | `eml`, `msg`, `mbox` | | Medical images (explicit opt-in) | `dcm`, `dicom` through `@file-viewer/renderer-dicom`; one bounded local Part 10 file, including multi-frame navigation | | Digital signatures (explicit opt-in) | `p7m`, `p7s`, `p7b`, `p7c`, `pkcs7`, `cms`, `cmsc`, `tsq`, `tsr`, `tst`, `tsd`, `asics`, `scs`, `asice`, `sce`, `ers`, `asc`, `sig`, `pgp`, `gpg`, `jws` through `@file-viewer/renderer-signature` | | Binary inspection (explicit opt-in) | `bin`, `hex`, `elf`, `exe`, `dll`, `class`, `macho` through `@file-viewer/renderer-binary`; a bounded, read-only byte inspector with no MIME wildcard or specialist-route override | | Diagrams and mind maps | `xmind`, `drawio`, `dio`, `excalidraw`, `mermaid`, `mmd`, `plantuml`, `puml` | | CAD and engineering | `dwg`, `dxf`, `dwf`, `dwfx`, `xps`, plus EDA files such as `gds`, `oas`, `oasis`, `olb`, `dra` | | 3D and geospatial | `gltf`, `glb`, `obj`, `stl`, `ply`, `step`, `stp`, `iges`, `ifc`, `3dm`, `brep`, `geojson`, `kml`, `gpx`, `shp`; opt-in `/geo3d`: `las`, `laz`, `copc`, GeoTIFF/COG, CityJSON, 3D Tiles, `3tz` | | Text, code, and data | Markdown, source code, logs, JSON, YAML, TOML, SQL, IPYNB, SQLite, WASM, Parquet, Avro | | Adobe design files (explicit opt-in) | `psd`, `psb`, `pdd`, `psdt`, `ai`, `ait`, `eps`, `ps`, `idml`, `icml`, `idms`, `inx`, `xd`, `indd`, `indt`, `fla`, `xfl`, `ase`, `aco`, `abr`, `csh`, `pat`, `grd`, `asl` through `@file-viewer/renderer-design` | | Media and assets | Images, SVG, HEIC, audio, video, HLS, and fonts | ## Office and Apple evidence boundary [#office-and-apple-evidence-boundary] * `xla`, `xlam`, `pot`, `dbf`, and `fb2` have real container fixtures, parser assertions, hashes, and Demo smoke cases. Macro and add-in code is never executed. * `pages`, `numbers`, and `key` include iWork '09 and modern IWA parser fixtures, bounded ZIP/Snappy/Protobuf parsing in a module Worker, a normalized static scene model, search/text layers, sheet/slide navigation, notes, and explicit encrypted-file detection. * `pages`, `numbers`, and `key` are **high-fidelity / stable**. The gate covers iWork '09, 2013+, and current Apple 15.3.1 native containers with exact structural assertions, real-browser smoke, and fixed-font visual goldens. Pages/Keynote use a 3% pixel-difference threshold and Numbers uses 5%; Quick Look images remain loading placeholders or explicit limited-preview fallbacks only. * Stable Apple support means static high fidelity: Keynote animations, transitions, and video are not executed; Numbers reads saved formula results instead of recalculating them; encrypted `iwpv2` files are detected and reported; missing fonts surface substitution information. * `wpd/wp/wp5/wp6` are **structured / stable**. A checksum-pinned MPL-2.0 libwpd/librevenge WebAssembly Worker extracts text, styles, tables, headers, footers, and notes from licensed genuine WP 4.2, 5.0, 5.1, and 6.x fixtures. Chromium, Firefox, and WebKit smoke the packaged Worker/WASM path; `wp5` and `wp6` remain routing aliases and renamed files do not count as fixture evidence. Macros are never executed, and bounded text is only a runtime fallback. * The binary inspector is experimental and explicit. It owns only seven binary-oriented extensions, parses a reviewed header catalog in a terminable module Worker, and shows raw bytes when no template matches. PNG, ZIP, WASM, `application/octet-stream`, editing, and user-authored templates are intentionally outside its routing contract. * `hwp/hwpx` are **structured / stable** with redistributable Apache-2.0 HWP v5 and HWPX fixtures. The gate covers page geometry, inline styles, merged tables, headers, footers, notes, and embedded images in Chromium, Firefox, and WebKit. Encrypted, DRM, and distribution documents are detected and rejected explicitly; rare controls and producer-specific layout constructs remain documented limitations. The full machine-readable matrix, including containers, levels, status, and limits, is generated from `ecosystem/format-catalog.json` into [`docs/generated/format-catalog.md`](/generated/format-catalog). ## Engineering Renderer Notes [#engineering-renderer-notes] * Adobe creative files use the explicit `@file-viewer/renderer-design` package. Local module Workers and WASM keep parsing off the main thread and make the path fully self-hostable. Fidelity follows the evidence available in each format: saved PSD/PSB composites and supported layer pixels; a verified PDF-compatible Illustrator surface by default; native AI/AIT PGF/private-source artboards, layers, paths, and bounded Canvas rendering through `illustrator-pgf`; IDML pages; structured InDesign exchange/modern XFL; embedded XD/INDD previews; deterministic resource previews; and experimental PostScript output. Unknown native Illustrator operators remain visible in fidelity diagnostics instead of being discarded, and unsupported gradients, complex text, images, plugins, effects, masks, blending, overprint, and color-management semantics are not claimed as complete reconstruction. * Word preview uses `@file-viewer/renderer-word`. The package lazy-loads `@file-viewer/docx`, `@file-viewer/doc`, and RTF/OpenDocument helpers only for DOCX/DOC/RTF/ODT files, so core-only and lightweight component installs do not pull Word engines by default. `msdoc-viewer` is a compatibility alias for `@file-viewer/doc`, not a separate parser. * Legacy DOC keeps separate Latin, East Asian and bidirectional font settings and distinguishes single/multiple, minimum and exact line spacing. Fonts come from the browser's installed fonts and fallbacks, not a public CDN; different installed fonts can still change glyphs and wrapping. The Demo includes the original WPS sales-contract sample. That file contains no tracked revisions, so it must not display invented deletion marks. * DOCX Worker auto mode requires a known `options.docx.workerUrl`, browser Worker support and a safe page protocol. Full packages supply the asset URL; a lightweight integration without it parses on the main thread rather than requesting a missing Worker. Explicit `worker: true` remains available with correctly deployed assets. * Spreadsheet preview uses `@file-viewer/renderer-spreadsheet` with `styled-exceljs` and `e-virt-table`. It preserves Office 365 and WPS in-cell images alongside workbook drawing images; double-clicking a rendered image opens a full-size preview that can be dismissed with Escape, the backdrop, or the close button. * Presentation preview uses `@file-viewer/renderer-presentation` with two isolated engines. Binary PowerPoint 97–2003 `.ppt` lazy-loads the packaged `@file-viewer/ppt@0.3.4` Worker/OffscreenCanvas/WASM engine and bounded frame cache; OpenXML files lazy-load `@file-viewer/pptx` and its separate Worker. Standard Demo, Vite/full, copy-assets, and CDN/IIFE layouts need no PPT runtime URL configuration; use `options.presentation.pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl` only for custom `.ppt` asset layouts and `workerUrl` / `workerType` for PPTX. * XMind uses `@file-viewer/renderer-mindmap` with XMind 8 XML and XMind 2020+ JSON package parsing, plus an `@panzoom/panzoom` powered canvas for drag panning, node-start dragging, mobile pinch zoom, keyboard panning, responsive fit-on-open/host-resize behavior, and unified toolbar state sync after pan/navigation. * Mermaid and PlantUML are handled by `@file-viewer/renderer-drawing`. Mermaid lazy-loads the official `mermaid` renderer and outputs theme-aware SVG. PlantUML stays offline by default with an SVG source preview; configure `options.drawing.plantumlServerUrl` when an intranet PlantUML SVG service is available. If the endpoint is unavailable, the viewer renders the same offline preview instead of leaving the page blank. Both diagram surfaces support drag panning and renderer-native zoom controls through `@panzoom/panzoom`. * Patch files are rendered with `diff2html` in side-by-side mode. Git bundles parse the bundle header, refs, commit objects, trees, readable blobs, and regular OFS_DELTA / REF_DELTA pack objects directly in the browser; very large packs or bundles that depend on external prerequisites surface a clear boundary notice instead of being silently misrepresented. * EDA uses `@file-viewer/renderer-eda`. OLB and DRA are safe structure previews over common CFB/OLE2 containers, standard GDSII renders small layouts as SVG and larger element sets through WebGL typed-array batches, readable OASIS text fixtures render as SVG, and real SEMI binary OASIS remains a safe structure-index preview until the dedicated WASM/WebGL layout kernel is split out. * CAD uses `@file-viewer/renderer-cad` and `@flyfish-dev/cad-viewer`; DWG, DWF, and DWFx assets remain self-hostable for offline deployments. * Archives use `@file-viewer/renderer-archive` with `libarchive.js` Worker + WASM first, then ZIP/TAR/GZIP compatibility fallback when the Worker cannot start. Legacy ZIP files without the UTF-8 filename flag are decoded with GBK/GB18030 detection so Chinese entry names remain readable in the compatibility path. * Media uses `@file-viewer/renderer-media` and native browser decoders first. When Chromium rejects an MPEG-4 Part 2 (`mp4v`) Simple Profile track, the renderer loads a dedicated Worker and the Apache-2.0 AOSP PacketVideo decoder. It uses the AAC track as the playback clock and draws decoded I420 frames to a Canvas. The WASM file is 111,379 bytes, or 34,410 bytes with gzip, and loads only after native decoding fails. The implementation contains no FFmpeg, libav, or LGPL/GPL/AGPL source. Files outside the decoder's current coverage get an explicit compatibility notice. * STEP, IGES, and BREP use the `@file-viewer/renderer-3d` entry plus the lightweight `@file-viewer/geometry-engine` route package and local OpenCascade/WASM decoding. The separate experimental `@file-viewer/renderer-3d/ifc` entry provides self-hosted That Open / Web-IFC preview when explicitly installed, as in the official Demo; it is not added to core, default component installs, or Full packages. 3DM remains signature and conversion guidance pending a dedicated `rhino3dm` path. * Streaming-first engineering/geospatial datasets use the explicit `@file-viewer/renderer-3d/geo3d` subpath. TIFF is content-sniffed so ordinary `.tif/.tiff` continues to use the image renderer; GeoTIFF/COG is routed only when geographic tags are present. COPC/COG/3D Tiles preserve random-access URLs, while 3TZ extraction is bounded and rejects unsafe archive paths. ## Binary PPT Engine License Boundary [#binary-ppt-engine-license-boundary] The public `@file-viewer/ppt` build renders `.ppt` files with its required visible watermark and keeps its own package license; it is not covered by File Viewer's Apache-2.0 license. Demo, Full, copy-assets, and CDN/IIFE outputs include its matching public runtime. Removing the PPT watermark requires commercial authorization. The integrity check also requires Web Crypto SHA-256, so deploy this path in a secure browser context (normally HTTPS or localhost). ## Capability Model [#capability-model] Each renderer reports what it can safely do. The common toolbar then shows download, print, HTML export, zoom, search, and navigation only when the active file type supports those operations. This avoids pretending that every format supports the same operations. Word and PDF can use full-page print adapters, images can zoom naturally, archives can lazy-extract nested entries, and virtual spreadsheet tables are provided by `@file-viewer/renderer-spreadsheet` to avoid fragile outer CSS scaling. ## Best Evaluation Path [#best-evaluation-path] 1. Open the [live demo](https://demo.file-viewer.app). 2. Try the sample closest to your production files. 3. Test your own file through upload or URL. 4. Use the [comparison demo](https://demo.file-viewer.app/compare.html) for contract, report, and generated-output review. 5. If a standard-package deployment is offline or CSP-restricted, run `npx --yes file-viewer-copy-assets ./public/file-viewer`; Full packages use their included same-version `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Point renderer assets to your own static path. --- # Docs Home (/guide) ## What To Read First [#what-to-read-first] | Goal | Page | | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | | Run the viewer in a project | [Quickstart](/guide/quickstart) | | Pick the right npm package | [Ecosystem packages](/guide/ecosystem) | | Embed the official demo without npm packages | [Quickstart: Zero-dependency integration](/guide/quickstart#zero-dependency-integration-official-demo-iframe) | | Choose minimal imports or composed presets | [2.1.0 modular import paths](/guide/ecosystem#_2-1-0-modular-import-paths) | | Keep host CSS from leaking into the viewer | [Style isolation and customization](/guide/style-isolation) | | Check format coverage | [Supported formats](/guide/formats) | | Understand npm, GitHub, releases, and self-hosted assets | [Distribution](/guide/distribution) | ## Main Links [#main-links] * Live demo: [demo.file-viewer.app](https://demo.file-viewer.app) * iframe demo entry: [demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx) * Document comparison demo: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html) * GitHub repository: [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer) * npm scope: [`@file-viewer`](https://www.npmjs.com/search?q=%40file-viewer) * GitHub Sponsors: [github.com/sponsors/wybaby168](https://github.com/sponsors/wybaby168) * WeChat / Alipay: [dev.flyfish.group/sponsor?source=github](https://dev.flyfish.group/sponsor?source=github) * Enterprise support: [dev.flyfish.group/shop](https://dev.flyfish.group/shop) ## Positioning [#positioning] File Viewer by Flyfish is not trying to replace specialist editors. It gives business products a practical, embedded preview layer for common and uncommon attachments: documents, spreadsheets, slides, PDFs, archives, email, diagrams, CAD drawings, 3D assets, code, logs, media, and data files. The project keeps a pure TypeScript core under `@file-viewer/core`, split renderer packages for heavier formats, native component packages for Web Components, Vue, React, jQuery, and Svelte, and product-shaped presets for common capability sets. The 2.1.0 architecture is modular by default: use minimal renderer imports when you need one exact format, or choose `preset-lite`, `preset-office`, `preset-engineering`, or `preset-all` when your product needs a composed capability set. In Vite projects, `@file-viewer/vite-plugin` auto-discovers installed presets and injects the capability layer, so most teams do not hand-write renderer imports. Every standard component defaults to Shadow DOM so uncontrolled global CSS cannot break the viewer. Theme customization should use `--file-viewer-*` tokens and stable `::part()` surfaces; use `options.styleIsolation:'none'` only for legacy deep overrides. For heavy users that need everything immediately, use the native Full package. It already includes `preset-all`; do not install or pass another preset: ```bash npm install @file-viewer/vue3-full npm install -D @file-viewer/vite-plugin # Vite ``` ```ts fileViewerRenderers({ copyAssets: true }) ``` Vite publishes complete assets in both dev and build. Webpack, Vue CLI, Rspack, Rollup, Umi, and other non-Vite projects run the same-version CLI included by the Full package: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` Script-tag deployments can publish the complete `@file-viewer/web-full/dist/` directory without a copy step. --- # Modular And On-demand Renderers (/guide/on-demand-renderers) The additive v3 `standard` profile, CLI plan, measured closure budget, and full-cutover blockers are documented in [V3 Modular Profiles](/guide/v3-modular-profiles). ## Minimal Import [#minimal-import] For a PDF-only Vue 3 product: ```bash npm install @file-viewer/vue3 @file-viewer/renderer-pdf ``` ```ts import { pdfRenderer } from '@file-viewer/renderer-pdf' const options = { rendererMode: 'replace', renderers: [pdfRenderer] } ``` This path is bundler-neutral and works in Webpack, Rspack, Rollup, Umi, classic multi-page apps, and micro-frontends. Vite projects can add the plugin to generate and inject the renderer import automatically: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ formats: ['pdf'], copyAssets: true, chunkStrategy: 'renderer' }) ] }) ``` `copyAssets` copies the offline payload that the installed packages provide. `@file-viewer/renderer-pdf` owns `@fontsource-variable/noto-sans-sc` as a runtime dependency, so direct renderer installs and every PDF preset self-host the CJK fallback automatically. `@file-viewer/assets-standard` remains the preferred pre-staged source for the standard profile. If neither source resolves, the installed dependency tree is incomplete and the build fails with an actionable error instead of silently dropping CJK fallback support. `pnpm test:pdf-cjk-font-github-242` verifies both the direct ownership and the required copied font/license payload. The plugin reads the Vite major installed by the application. Vite 5–7 receive `build.rollupOptions.output.manualChunks`; Vite 8 receives `build.rolldownOptions.output.codeSplitting.groups`. Existing application groups, priorities, array outputs, and `codeSplitting:false` are preserved, so the plugin adds only its stable CodeMirror and renderer groups. ## Presets [#presets] | Preset | Best for | | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | `@file-viewer/preset-lite` | Text, code, Markdown, image, audio, and video attachments | | `@file-viewer/preset-standard` | Common Office/PDF/OFD/archive/email/text/media formats without specialist or legacy-heavy capabilities | | `@file-viewer/preset-office` | PDF, Word, spreadsheet, presentation, OFD, and OpenDocument workflows | | `@file-viewer/preset-engineering` | CAD, EDA, Typst, archives, email, data, 3D, geo, drawing, and mind maps | | `@file-viewer/preset-all` | Admin workbenches that need the published compatibility renderer set, including CHM; later specialist capabilities remain explicit | ## Optional Specialist Renderers [#optional-specialist-renderers] Since 3.1.2, [BPMN diagrams](/guide/bpmn) and [XML validation and transformation profiles](/guide/xml-profiles) are available as explicit opt-ins. Neither is automatically enabled by Full packages. Adobe design, DICOM, digital-signature inspection, and binary inspection are explicit opt-ins. They are not dependencies of the eight published `@file-viewer/*-full` packages or the frozen `@file-viewer/preset-all` compatibility baseline. This preserves the published Full contract and prevents specialist Worker/WASM, medical-imaging, cryptographic, or binary-analysis dependencies from appearing during an ordinary upgrade. | Optional renderer | Formats | Direct npm install | CLI selection | What the viewer shows | | ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Adobe design** (`@file-viewer/renderer-design`) | `.psd`, `.psb`, `.pdd`, `.psdt`, `.ai`, `.ait`, `.eps`, `.ps`, `.idml`, `.icml`, `.idms`, `.inx`, `.xd`, `.indd`, `.indt`, `.fla`, `.xfl`, `.ase`, `.aco`, `.abr`, `.csh`, `.pat`, `.grd`, `.asl` | `npm install @file-viewer/renderer-design` | `npx file-viewer-cli config add psd --write` | Browser-local Worker/WASM previews for saved Photoshop pixels and supported layers; verified PDF-compatible Illustrator plus switchable native PGF artboards/layers/paths through `illustrator-pgf`; IDML and exchange structures; embedded XD/INDD previews; modern XFL; palettes; Photoshop resources; and PostScript. Unsupported native operators and fidelity limits remain explicit. | | **DICOM** (`@file-viewer/renderer-dicom`) | `.dcm`, `.dicom` | `npm install @file-viewer/renderer-dicom` | `npx file-viewer-cli config add dicom --write` | One local DICOM Part 10 file, including multi-frame navigation, window width/center, zoom, pan, rotation, fit-to-view, and basic metadata. It does not assemble studies or provide PACS/DICOMweb, MPR, segmentation, or diagnosis. | | **Digital signatures** (`@file-viewer/renderer-signature`) | `.p7m`, `.p7s`, `.p7b`, `.p7c`, `.pkcs7`, `.cms`, `.cmsc`, `.tsq`, `.tsr`, `.tst`, `.tsd`, `.asics`, `.scs`, `.asice`, `.sce`, `.ers`, `.jws`, `.asc`, `.sig`, `.pgp`, `.gpg` | `npm install @file-viewer/renderer-signature` | `npx file-viewer-cli config add p7m --write` | Bounded browser-local inspection of CMS/PKCS#7, selected CAdES data, timestamps, ASiC containers, evidence records, JWS, and public OpenPGP inputs. Parsing, digest, signature, and timestamp results are reported separately. | | **Binary inspector** (`@file-viewer/renderer-binary`) | `.bin`, `.hex`, `.elf`, `.exe`, `.dll`, `.class`, `.macho` | `npm install @file-viewer/renderer-binary` | `npx file-viewer-cli config add bin --write` | Read-only, browser-local offset/hex/ASCII view with a bounded module Worker, virtual rows, typed values, and a reviewed ELF, PE/COFF, Mach-O, PNG, ZIP, WebAssembly, and Java-class header catalog. It never claims `application/octet-stream` or displaces a dedicated renderer. | | **Streaming Geo3D** (`@file-viewer/renderer-3d/geo3d`) | `.las`, `.laz`, `.copc`, GeoTIFF/COG, CityJSON, `tileset.json`, `.3tz` | `npm install @file-viewer/renderer-3d @giro3d/giro3d@2.0.5` (add `jszip@3.10.2` for 3TZ) | Manual subpath registration | Explicit Giro3D-powered streaming/range preview. Ordinary TIFF stays on the image renderer unless GeoTIFF tags are detected; COPC/COG/3D Tiles keep progressive URL access; 3TZ extraction is bounded and path-safe. Copy self-hosted decoder assets with `npx file-viewer-geo3d-assets public/file-viewer/vendor/geo3d`. | DICOM installations, including CLI `--profile full`, need the application's root dependency overrides and Node.js requirements described in the packaged [DICOM installation policy](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/dicom/README.en.md#application-installation-policy). The default dependency graph still has audit findings; the workspace policy is not inherited by consumers. Qualify the resulting application and browser behavior before deployment. ### I already use a Full package. How do I enable an optional renderer? [#i-already-use-a-full-package-how-do-i-enable-an-optional-renderer] The same rule applies to `@file-viewer/web-full`, `@file-viewer/vue3-full`, `@file-viewer/vue2.7-full`, `@file-viewer/vue2.6-full`, `@file-viewer/react-full`, `@file-viewer/react-legacy-full`, `@file-viewer/jquery-full`, and `@file-viewer/svelte-full`. Keep the Full package installed, then add only the specialist renderer the application needs. The following example enables five specialist renderers; remove any package, import, and array entry that the application does not need: ```bash npm install @file-viewer/renderer-binary @file-viewer/renderer-design @file-viewer/renderer-dicom @file-viewer/renderer-signature @file-viewer/renderer-3d @giro3d/giro3d@2.0.5 ``` ```ts import { binaryRenderer } from '@file-viewer/renderer-binary' import { designRenderer } from '@file-viewer/renderer-design' import { dicomRenderer } from '@file-viewer/renderer-dicom' import { signatureRenderer } from '@file-viewer/renderer-signature' import { createGeo3dRenderer } from '@file-viewer/renderer-3d/geo3d' const geo3dRenderer = createGeo3dRenderer({ assetBaseUrl: '/file-viewer/vendor/geo3d/', }) const options = { rendererMode: 'extend', renderers: [binaryRenderer, designRenderer, dicomRenderer, signatureRenderer, geo3dRenderer] } ``` `rendererMode: 'extend'` keeps the preset supplied by the Full package and appends these renderers. Use `replace` only when the explicitly configured renderers should become the complete set. #### CLI-managed projects [#cli-managed-projects] Run any relevant `config add` commands, then install the resulting plan: ```bash # Adobe design npx file-viewer-cli config add psd --write # DICOM npx file-viewer-cli config add dicom --write # Digital-signature containers npx file-viewer-cli config add p7m --write # Binary inspection npx file-viewer-cli config add bin --write npx file-viewer-cli install --yes ``` Use `npx file-viewer-cli list` to inspect the current catalog before changing a project. > Directly installing a Full package and selecting the CLI `full` profile are intentionally different. A Full package keeps the published `preset-all` compatibility baseline. The CLI `full` profile keeps that package and defaults to the established DICOM/signature additions; Adobe design and binary inspection are added only when `config add`, `--formats`, or `--capabilities` explicitly selects them, after their weight and license boundaries are shown. ### Using a prebuilt `web-full` browser bundle? [#using-a-prebuilt-web-full-browser-bundle] The downloadable `web-full` IIFE bundle contains the published Full renderer set. Adobe design, DICOM, digital-signature, and binary-inspector renderers are not embedded in that bundle. Use a package-manager project or the File Viewer CLI when the integration needs an optional renderer. Copying a renderer package next to the prebuilt bundle does not register it. The digital-signature renderer can pass safely extracted PDF, XML, image, Office, or other supported content back through the nested-renderer pipeline, so keep the matching normal renderer available when that preview is required. Cryptographic verification does not establish certificate or key trust, qualified-signature status, policy compliance, or legal validity. ### Binary inspector boundary [#binary-inspector-boundary] Use the binary inspector only when an application explicitly asks for byte-level inspection. It has no MIME wildcard route and does not replace PNG, ZIP, WASM, or other specialist renderers. The first catalog is read-only and bounded to a 16 MiB whole-file default, 5 seconds of parsing, 512 structure nodes, 16 levels of nesting, and 4 KiB decoded strings; over-limit input fails clearly instead of doing a partial arbitrary scan. A one-shot module Worker parses each input and terminates after a result, error, timeout, or cancellation. The hex grid virtualizes rows, so large accepted inputs do not create one DOM node per byte. ## Renderer Package Reference [#renderer-package-reference] Install a single renderer when a product needs the smallest possible capability set: | Renderer package | Export | Main pipeline | | ------------------------------------ | ---------------------- | --------------------------------------------------------------------------------------------------------------------- | | `@file-viewer/renderer-pdf` | `pdfRenderer` | PDF | | `@file-viewer/renderer-word` | `wordRenderer` | DOCX, DOC, DOT, RTF, ODT | | `@file-viewer/renderer-spreadsheet` | `spreadsheetRenderer` | Excel, OpenDocument spreadsheet, CSV-like tables | | `@file-viewer/renderer-pptx` | `pptxRenderer` | Modern OpenXML PowerPoint without the legacy PPT runtime | | `@file-viewer/renderer-ppt` | `pptRenderer` | Optional legacy binary `.ppt` / `.pot` runtime | | `@file-viewer/renderer-presentation` | `presentationRenderer` | Compatibility aggregate for both PowerPoint families | | `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD | | `@file-viewer/renderer-cad` | `cadRenderer` | DWG, DXF, DWF, DWFx, XPS | | `@file-viewer/renderer-3d` | `modelRenderer` | 3D models and lightweight geometry signatures | | `@file-viewer/renderer-design` | `designRenderer` | PSD/PSB/PDD/PSDT, AI/AIT, EPS/PS, IDML/ICML/IDMS/INX, XD, INDD/INDT, modern FLA/XFL, ASE/ACO, and ABR/CSH/PAT/GRD/ASL | | `@file-viewer/renderer-dicom` | `dicomRenderer` | Selected local DICOM Part 10 single-file and multi-frame preview in the standard Viewer entry | | `@file-viewer/renderer-signature` | `signatureRenderer` | Selected CMS/CAdES, timestamp, ASiC, evidence-record, JWS, and public OpenPGP inspection in the standard Viewer entry | Binary PowerPoint and OpenXML PowerPoint now have separate npm renderer packages. The compatibility aggregate keeps the existing root and subpath APIs. The packaged `.ppt` 0.3.4 runtime is zero-config in layouts that explicitly install it; for custom asset layouts, configure `presentation.pptModuleUrl` / `pptWorkerUrl` / `pptWasmUrl` / `pptFontUrl`. PPTX continues to use `presentation.workerUrl` / `workerType`. Strict PPTX-only applications should import `pptxRenderer` from `@file-viewer/renderer-pptx`, or configure `fileViewerRenderers({ formats: ['pptx'] })`. Both paths exclude the classic `.ppt` package, font, and WASM from the install and production closure. Existing `@file-viewer/renderer-presentation/pptx` imports remain compatible. The binary-only package is `@file-viewer/renderer-ppt`. \| `@file-viewer/renderer-drawing` | `drawingRenderer` | draw\.io, Excalidraw, Mermaid, PlantUML | \| `@file-viewer/renderer-mindmap` | `mindmapRenderer` | XMind | \| `@file-viewer/renderer-geo` | `geoRenderer` | GeoJSON, KML, GPX, SHP | \| `@file-viewer/renderer-typst` | `typstRenderer` | Typst source rendered through local WASM assets | \| `@file-viewer/renderer-archive` | `archiveRenderer` | Archives and nested file preview | \| `@file-viewer/renderer-chm` | `chmRenderer` | CHM contents, index, search, internal links, and local Rust/WASM topic extraction | \| `@file-viewer/renderer-email` | `emailRenderer` | EML, MSG, MBOX | \| `@file-viewer/renderer-epub` | `ebookRenderer` | EPUB, UMD | \| `@file-viewer/renderer-text` | `textRenderer` | Markdown, highlighted code, patch, git bundle | \| `@file-viewer/renderer-image` | `imageRenderer` | Image and HEIC / HEIF paths | \| `@file-viewer/renderer-media` | `mediaRenderer` | Audio, video, HLS, MIDI summaries | \| `@file-viewer/renderer-data` | `dataRenderer` | PSD, fonts, SQLite, Parquet, Avro, WASM, WebArchive | \| `@file-viewer/renderer-eda` | `edaRenderer` | OLB, DRA, GDS, OAS/OASIS | Engine packages such as `@file-viewer/pptx`, `@file-viewer/geometry-engine`, `@file-viewer/eda-layout`, and `@file-viewer/eda-orcad` are maintained for renderer internals and advanced reuse. Normal viewer integrations should use the renderer or preset package above. ### CHM with a self-hosted Rust/WASM Worker [#chm-with-a-self-hosted-rustwasm-worker] Install the standalone renderer when an application only needs Compiled HTML Help: ```bash npm install @file-viewer/vue3 @file-viewer/renderer-chm ``` ```ts import { chmRenderer } from '@file-viewer/renderer-chm' const options = { rendererMode: 'replace', renderers: [chmRenderer] } ``` Vite projects can instead select `formats: ['chm']` with `copyAssets:true`. `preset-all` and the Full packages already include the renderer, but the deployment must still publish these version-matched files under `file-viewer/vendor/chm/`: * `chm.worker.js` * `chm_wasm.js` * `chm_wasm_bg.wasm` The Vite plugin and the same-version asset copy CLI publish that directory automatically. A custom asset layout can override it with `options.chm.workerUrl`, `options.chm.wasmModuleUrl`, and `options.chm.wasmUrl`; do not point production deployments at a public CDN. The archive is parsed locally in a dedicated Worker. Topic HTML is sanitized before display and rendered in an iframe sandbox without `allow-scripts`; a restrictive CSP also disables scripts, plugins, forms, base-URL rewriting, and automatically loaded remote active content. Internal `ms-its:` / `mk:@MSITStore` links and packaged resources are resolved back into the current CHM instead of receiving network access. This is a read-only documentation viewer, not an ActiveX-compatible HTML Help runtime. ## Automatic Preset Assembly [#automatic-preset-assembly] For an Office document platform, the bundler-neutral path is: ```bash npm install @file-viewer/vue3 @file-viewer/preset-office ``` ```ts import officePreset from '@file-viewer/preset-office' const options = { rendererMode: 'replace', preset: officePreset } ``` `@file-viewer/vite-plugin` can discover installed presets and inject the generated virtual module into the Vite HTML entry. In Vite projects, add the plugin once and the framework component automatically receives that preview capability without a manual preset import: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts fileViewerRenderers({ copyAssets: true // No preset option required: installed @file-viewer/preset-* packages are discovered. }) ``` `inject` defaults to true. Preset packages register themselves in core when imported, and `FileViewerOptions.autoRenderers` defaults to true in normal `extend` mode. Set `autoRenderers:false` only when a product needs full manual control. The default experience is intentionally zero-config: if the plugin receives no explicit `preset`, `formats`, or `renderers`, or only receives `copyAssets:true`, it auto-discovers installed `@file-viewer/preset-*` packages. `preset-all` takes precedence when present; otherwise installed `lite`, `office`, and `engineering` presets are composed. Install `@file-viewer/preset-all` when an application needs the published compatibility baseline. Adobe design, DICOM, digital signatures, and binary inspection remain explicit: ```bash npm install @file-viewer/vue3 @file-viewer/preset-all # Vite projects add the plugin: npm install -D @file-viewer/vite-plugin ``` Use `preset:'auto'` or `autoPresets:true` when you also enable `scan:true`; this keeps installed preset discovery active while source hints add extra renderers. If `preset-all` is installed, it takes precedence to avoid importing narrower presets twice. ```ts fileViewerRenderers({ preset: 'auto', scan: true, formats: ['pdf'], copyAssets: true, chunkStrategy: 'renderer' }) ``` | Customization | Purpose | | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | | `copyAssets:true` | Copies matched Worker, WASM, font, PDF/CAD/Typst/Archive/CHM/Data, and vendor assets, including the three files under `vendor/chm/` | | `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-discovery active together with `scan:true` | | `formats` / `renderers` | Adds a few formats outside a preset, or builds a strict single-renderer bundle | | `scan:true` | Collects format hints from `fileViewerFormats`, `data-file-viewer-formats`, `accept`, and similar source hints | | `inject:false` | Disables auto injection so application code imports `virtual:file-viewer-renderers` and passes `options.renderers` manually | | `chunkStrategy:'renderer'` | Uses renderer-level chunk names for caching and heavy-pipeline size debugging | ## Manual Control [#manual-control] Strict bundles can still use the virtual module directly: ```ts fileViewerRenderers({ formats: ['pdf'], inject: false, copyAssets: true }) ``` ```ts import { configuredFileViewerRenderers } from 'virtual:file-viewer-renderers' const options = { rendererMode: 'replace', renderers: configuredFileViewerRenderers } ``` `scan:true` detects hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes, then merges them with explicit `formats`. ## Missing Renderer Guidance [#missing-renderer-guidance] If a file extension is in the supported matrix but its renderer has not been assembled, the viewer shows a friendly install-oriented state. For example, opening `.pdf` without the PDF renderer recommends `@file-viewer/preset-office` or `@file-viewer/renderer-pdf`. Only extensions outside the matrix are shown as truly unsupported. ## Asset Rules [#asset-rules] Use `copyAssets:true` or `npx --yes file-viewer-copy-assets ./public/file-viewer` for standard-package offline deployments. Full packages include the matching CLI and use `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Worker, WASM, font, PDF, CAD, Typst, Archive, CHM, Data, and Draw\.io assets should be served from your own domain. A CHM deployment is complete only when `vendor/chm/chm.worker.js`, `vendor/chm/chm_wasm.js`, and `vendor/chm/chm_wasm_bg.wasm` are available with JavaScript and WebAssembly MIME types. ## CHM Completion Checklist [#chm-completion-checklist] * [x] `@file-viewer/renderer-chm` is available as a standalone renderer and is included by `preset-all` / Full packages. * [x] The Rust/WASM parser runs in a dedicated Worker, and standard asset tooling self-hosts the Worker, JavaScript bridge, and WASM binary under `vendor/chm/`. * [x] Contents, keyword index, text search, internal navigation, and packaged resources stay within the current archive. * [x] Topic documents are sanitized, scripts remain disabled by sandbox and CSP, and remote active content is not loaded automatically. ## Optional streaming Geo3D viewer [#optional-streaming-geo3d-viewer] The explicit `@file-viewer/renderer-3d/geo3d` entry adds the streaming-first geospatial formats without changing the ordinary 3D renderer or any Full preset. It covers LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles and bounded 3TZ archives. Regular TIFF stays on the image renderer unless bounded TIFF metadata inspection finds GeoTIFF tags. COPC/COG/3D Tiles keep URL/File random-access semantics where the source format supports them. Install the optional Giro3D peer and copy its decoder assets locally with `file-viewer-geo3d-assets`. See [`GEO3D.md`](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/3d/GEO3D.md) for detection, range/CORS, 3TZ safety, samples and deployment details. ## Optional IFC BIM viewer [#optional-ifc-bim-viewer] The explicit `@file-viewer/renderer-3d/ifc` entry enhances only IFC files with local That Open / Web-IFC visualization, selection, properties and a configuration hook. Existing Full/Office entry points remain unchanged. Install the optional peers and self-host their matching Worker/WASM assets with `file-viewer-ifc-assets`. The exact setup and licensing notes are in the package's [IFC guide](https://github.com/flyfish-dev/file-viewer/blob/main/packages/renderers/3d/IFC.md). --- # Overview (/guide/overview) ## What It Solves [#what-it-solves] File Viewer by Flyfish lets users preview business attachments without downloading every file or sending private documents to a conversion backend. It covers Office documents, PDF/OFD, Typst, CAD, EDA, archives, email, diagrams, mind maps, 3D, media, code, and structured data through lazy renderer packages. The canonical catalog declares **275 registered extensions** across **47 preview pipelines**: **225 stable** and **50 experimental**. ## Architecture [#architecture] | Layer | Responsibility | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------- | | `@file-viewer/core` | Framework-neutral contracts, renderer registry, events, assets, lifecycle, search, zoom, print, export, and shared utilities | | Renderer packages | Heavy format-specific engines such as PDF, Word, Presentation, CAD, Typst, Archive, Email, EPUB, Drawing, Data, and EDA | | Presets | Product-shaped renderer bundles: `preset-lite`, `preset-office`, `preset-engineering`, and `preset-all` | | Component packages | Native integrations for Vanilla JS / Web Component, Vue, React, Svelte, and jQuery | | Apps | Official site, documentation site, main demo, comparison demo, and component demos | Core stays pure TypeScript and framework-neutral. Component packages depend on core and expose native APIs for their ecosystem. ## Why Modular [#why-modular] Most products do not need every heavy engine on first load. Install a minimal renderer set for a focused product, or use a preset when you need broader coverage. Worker, WASM, font, and vendor assets remain self-hostable for intranet and strict-CSP deployments. The bundler-neutral path is `options.preset` / `options.renderers`: import the preset or renderer package and pass it to the component. In Vite projects, `@file-viewer/vite-plugin` is an optional assembly layer that removes manual imports after one plugin registration. It auto-discovers installed `@file-viewer/preset-*` packages and injects the matching capability registry, so the default Vite setup is still `fileViewerRenderers({ copyAssets:true })`. Use `@file-viewer/preset-all` for the fastest full-capability start, or explicit `formats`, `renderers`, `scan:true`, and `inject:false` only when a product needs strict bundle control. Every standard component uses Shadow DOM by default so uncontrolled host CSS cannot break the viewer. Theme customization stays stable through `--file-viewer-*` tokens and `::part()`; use `options.styleIsolation:'none'` only for legacy deep overrides. See [Style Isolation And Customization](/guide/style-isolation). ## Main Entry Points [#main-entry-points] * Official site: [file-viewer.app](https://file-viewer.app) * Documentation: [doc.file-viewer.app](https://doc.file-viewer.app) * Live demo: [demo.file-viewer.app](https://demo.file-viewer.app) * iframe demo entry: [demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx](https://demo.file-viewer.app/iframe.html?url=/example/en/calibre-demo.docx) * Comparison demo: [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html) * GitHub: [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer) --- # React Integration (/guide/quickstart-react) ## Install [#install] ```bash npm install @file-viewer/react @file-viewer/preset-office ``` Installing only `@file-viewer/react` gives you the lightest React component and core foundation. PDF, Office, CAD, Typst, archive, and other heavy format capabilities come from presets or renderer packages. The stable path for every bundler is to import a preset or renderer and pass it through `options.preset` / `options.renderers`: ```tsx import officePreset from '@file-viewer/preset-office' const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', styleIsolation: 'shadow', toolbar: { position: 'bottom-right' } } ``` React uses Shadow DOM by default so host global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization. Vite projects can add the plugin once to avoid manual preset imports. Vite still requires a one-line plugin registration; after that, `fileViewerRenderers({ copyAssets:true })` auto-discovers installed `@file-viewer/preset-*` packages: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true }) ] }) ``` Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when heavy users need the complete capability set immediately. Non-Vite apps keep passing the preset through `options.preset`; Vite apps keep the same plugin config: ```bash npm install @file-viewer/react @file-viewer/preset-all ``` Use a full package when you want one package to enable the complete matrix. React 18 / 19 uses `@file-viewer/react-full`; React 16.8 / 17 uses `@file-viewer/react-legacy-full`: ```bash npm install @file-viewer/react-full ``` ```tsx import FileViewer from '@file-viewer/react-full' export function Preview() { return (
) } ``` `@file-viewer/react-full` and `@file-viewer/react-legacy-full` already include `preset-all`; do not install or pass it again. For complete assets, Vite keeps the plugin configuration above and automatically serves/copies the matching payload in dev and build. CRA, Webpack, Rspack, or other non-Vite builds run the Full package's same-version CLI once for the public directory: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only when the product needs explicit control. The recommended default remains `fileViewerRenderers({ copyAssets:true })`, with installed presets auto-activated by the plugin. ## Component Usage [#component-usage] ```tsx import { useRef } from 'react' import FileViewer, { type FileViewerHandle } from '@file-viewer/react' import officePreset from '@file-viewer/preset-office' export function Preview() { const viewerRef = useRef(null) return (
console.log(event.type)} />
) } ``` ## Legacy React [#legacy-react] React 16.8 and 17 projects should use: ```bash npm install @file-viewer/react-legacy ``` The event and options model stays aligned with `@file-viewer/react`. ## Mobile, H5, And React Native WebView [#mobile-h5-and-react-native-webview] The React component works in mobile browsers and H5 WebViews. Give the host container a stable viewport height, keep `minHeight: 0`, and place the common toolbar at the bottom right so document content stays readable. PDF, Word, PPTX, images, CAD, XMind, Mermaid, PlantUML, and similar renderers fit to the available width first; zoom in/out/reset should go through the viewer controller or built-in toolbar instead of wrapping the rendered content with outer CSS transforms. ```tsx import FileViewer from '@file-viewer/react' import officePreset from '@file-viewer/preset-office' export function MobilePreview() { return (
) } ``` React Native cannot mount the DOM component directly. Use a `WebView` that loads an H5 viewer route or an `@file-viewer/web-full` IIFE page, then pass file URLs, authorization tokens, or Blob URLs through your app bridge. Enable JavaScript, DOM Storage, and the download capability in the WebView. For strict CSP or offline intranet deployments, keep using `file-viewer-copy-assets` or `@file-viewer/vite-plugin` with `copyAssets:true` so worker, WASM, font, and vendor assets are served from your own domain. ## Vite And Assets [#vite-and-assets] For Full packages, Vite uses `fileViewerRenderers({ copyAssets:true })`; non-Vite builds use the included `npx --no-install file-viewer-copy-assets ./public/file-viewer`. Both paths keep matching Worker/WASM/font/vendor assets self-hosted under the deployment base. --- # Svelte Integration (/guide/quickstart-svelte) ## Install [#install] Use the standard package when you want a light entry plus an explicit preset: ```bash npm install @file-viewer/svelte @file-viewer/preset-office ``` Use the full package when you want the complete matrix by default: ```bash npm install @file-viewer/svelte-full ``` `@file-viewer/svelte-full` enables `@file-viewer/preset-all` automatically while keeping the same component, action, event, and controller APIs. The package-root default export is the Svelte component. Import actions and lower-level controller helpers only from the explicit `/action` and `/controller` subpaths. ## Component Usage [#component-usage] ```svelte
``` Svelte uses Shadow DOM by default so uncontrolled host CSS cannot break the toolbar or renderer content. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization. The full package only changes the import: ```svelte
``` ## Action Usage [#action-usage] For pages that do not want a component instance, mount the action on any existing container: ```svelte
``` The full-package action uses the matching explicit entry: ```ts import { fileViewer } from '@file-viewer/svelte-full/action' ``` ## Vite Auto Assembly [#vite-auto-assembly] SvelteKit / Vite projects can register the plugin so installed presets activate automatically and Worker / WASM / font / vendor assets are copied: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default { plugins: [ fileViewerRenderers({ copyAssets: true }) ] } ``` When `@file-viewer/svelte-full` is installed, this configuration recognizes it and publishes the complete matching asset payload in dev and build. The Full package already includes `preset-all`; do not install or pass another preset. Non-Vite Full builds run the included same-version CLI: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` Non-Vite standard-package projects keep using `options.preset` / `options.renderers` explicitly. --- # Vue 2 Integration (/guide/quickstart-vue2) > Vue 2 is upstream end-of-life. File Viewer will keep its Vue 2.6/2.7 compatibility packages, but new applications should prefer Vue 3. Security-sensitive legacy applications should also assess the host framework's [GHSA-5j4c-8p2g-v4jx](https://github.com/advisories/GHSA-5j4c-8p2g-v4jx), because no patched Vue 2 release is available. ## Vue 2.7 [#vue-27] ```bash npm install @file-viewer/vue2.7 @file-viewer/preset-office ``` Installing only `@file-viewer/vue2.7` gives you the lightest native Vue 2.7 component. Add presets or renderer packages for concrete PDF, Office, CAD, Typst, archive, and engineering formats. For Webpack, Rspack, Rollup, Umi, and non-Vite applications, pass the capability through `options.preset`: ```ts import officePreset from '@file-viewer/preset-office' const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', styleIsolation: 'shadow', toolbar: { position: 'bottom-right' } } ``` Vue 2 uses Shadow DOM by default so aggressive global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for tokens and `::part()` customization. Vite projects can add the plugin to avoid manual preset imports. Installing the package alone is not enough because Vite plugins must be registered once; after registration the plugin auto-discovers installed presets: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true }) ] }) ``` ```ts import Vue from 'vue' import FileViewer from '@file-viewer/vue2.7' Vue.use(FileViewer) ``` ```vue ``` ## Vue 2.6 [#vue-26] ```bash npm install @file-viewer/vue2.6 @file-viewer/preset-office ``` Use the same component API as Vue 2.7. Keep your host container at a fixed or viewport-relative height. Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when heavy users need the full format matrix in one install: ```bash npm install @file-viewer/vue2.6 @file-viewer/preset-all ``` Full packages are also available when you want the complete matrix by default: use `@file-viewer/vue2.7-full` for Vue 2.7 and `@file-viewer/vue2.6-full` for Vue 2.6. ```bash npm install @file-viewer/vue2.7-full ``` ```ts import Vue from 'vue' import FileViewer from '@file-viewer/vue2.7-full' Vue.use(FileViewer) ``` `@file-viewer/vue2.7-full` and `@file-viewer/vue2.6-full` already include `preset-all`; do not install or pass it again. With the Vite configuration above, dev and build publish the complete matching assets automatically. Vue CLI, webpack 4, Rspack, Rollup, and other non-Vite projects run the Full package's included same-version CLI: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only for explicit registry control. Normal projects should keep `fileViewerRenderers({ copyAssets:true })` and let the plugin auto-activate installed presets. ## Vue 2.6 + Vue CLI 3 / webpack 4 [#vue-26--vue-cli-3--webpack-4] If importing `@file-viewer/preset-office` breaks the build but commenting it out lets the app compile, the Vue 2.6 component is usually not the failing part. The office preset pulls PDF, Word, Excel, PPTX, and OFD renderer dependencies into the bundle; Vue CLI 3 / webpack 4 does not transpile `node_modules` by default and does not understand every package `exports` subpath or `import.meta.url` worker pattern. The repository includes a standalone runnable demo based on this legacy stack: ```bash cd examples/vue2.6-cli3-office npm install npm run serve ``` On Node 17+, webpack 4 may need: ```bash NODE_OPTIONS=--openssl-legacy-provider npm run build ``` Prefer copying the demo `vue.config.js` first, then trim it after the customer build is stable. Current `@file-viewer/renderer-pdf` tarballs already isolate the staged PDF.js webpack runtime, so consumer projects must not add a loader for renderer-internal `dist/vendor/pdfjs` paths. ```js // vue.config.js const path = require('path') const resolveApp = value => path.resolve(__dirname, value) const resolvePackageRoot = packageName => path.dirname(require.resolve(`${packageName}/package.json`)) const resolvePackageFile = (packageName, relativePath) => path.join(resolvePackageRoot(packageName), relativePath) module.exports = { transpileDependencies: [ /@file-viewer/, /pdfjs-dist/, /e-virt-table/, /styled-exceljs/ ], configureWebpack: { resolve: { alias: { '@file-viewer/core/assets$': resolvePackageFile('@file-viewer/core', 'dist/assets.js'), '@file-viewer/core/browser$': resolvePackageFile('@file-viewer/core', 'dist/browser.js'), '@file-viewer/core/headless$': resolvePackageFile('@file-viewer/core', 'dist/headless.js'), '@file-viewer/docx$': resolvePackageFile('@file-viewer/docx', 'dist/docx-preview.mjs') }, extensions: ['.mjs', '.js', '.vue', '.json'] } } } ``` The renderer build isolates all four PDF.js runtime bindings (`modules`, `module_cache`, `exports`, and `require`) before publishing the tarball and records the source hash, transform count, and output hash in `dist/vendor/pdfjs/provenance.json`. This prevents PDF.js' inner webpack bootstrap from shadowing webpack 4's host exports. A project that separately imports `pdfjs-dist` source modules still owns compatibility for those direct imports; the File Viewer example uses that package only as a build-time source for copied static assets. Keep the `@file-viewer/docx` alias too: webpack 4 otherwise prefers the UMD `browser` entry, whose CommonJS exports are lost after Babel transpilation and surface as `@file-viewer/docx did not expose a compatible renderAsync function` when a DOCX is uploaded. The other patch, `build/babel-transform-import-meta-url.cjs`, lets webpack 4 parse the PPTX worker module. The copy script publishes the complete nine-file `@file-viewer/ppt@0.3.4` runtime under `public/file-viewer/vendor/ppt/` together with the PPTX worker. The `serve` env files set `NODE_ENV=production` to avoid Vue CLI 3.1 injecting its HMR client into this legacy preview path. Then pass the preset and self-hosted asset URLs explicitly: ```js import officePreset from '@file-viewer/preset-office' const assetBaseUrl = './file-viewer/' export const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', styleIsolation: 'shadow', pdf: { workerUrl: `${assetBaseUrl}vendor/pdf/pdf.worker.mjs`, cMapUrl: `${assetBaseUrl}vendor/pdf/cmaps/`, wasmUrl: `${assetBaseUrl}vendor/pdf/wasm/`, standardFontDataUrl: `${assetBaseUrl}vendor/pdf/standard_fonts/` }, docx: { workerUrl: `${assetBaseUrl}vendor/docx/docx.worker.js`, workerJsZipUrl: `${assetBaseUrl}vendor/docx/jszip.min.js` }, presentation: { pptModuleUrl: `${assetBaseUrl}vendor/ppt/index.mjs`, pptWorkerUrl: `${assetBaseUrl}vendor/ppt/worker.mjs`, pptWasmUrl: `${assetBaseUrl}vendor/ppt/ppt-native.wasm`, pptFontUrl: `${assetBaseUrl}vendor/ppt/ppt-font-cjk.otf`, workerUrl: `${assetBaseUrl}vendor/pptx/pptx.worker.js` }, spreadsheet: { workerUrl: `${assetBaseUrl}vendor/xlsx/sheet.worker.js` } } ``` `preset-office` covers PDF, Word, spreadsheets, presentations, OFD, and OpenDocument. It intentionally does not include images or media. Add those renderers explicitly when the application also previews `.jpg` or `.mp4`, or combine the office and lite presets: ```js import officePreset from '@file-viewer/preset-office' import { imageRenderer } from '@file-viewer/renderer-image' import { mediaRenderer } from '@file-viewer/renderer-media' export const viewerOptions = { preset: officePreset, renderers: [imageRenderer, mediaRenderer], rendererMode: 'replace' } ``` Those four `ppt*Url` values are only needed because this Vue CLI 3 compatibility example explicitly self-hosts assets from `public/file-viewer/`. The copy command and options file are already wired together; normal Vite/full-package installs publish and resolve the same packaged runtime automatically. Vue CLI 3 / webpack 4 can keep working for modern browsers. If a project still requires IE11-level output or an old `uglifyjs-webpack-plugin` pass over the full office dependency graph, prefer upgrading the minifier/build chain or isolating the viewer through `@file-viewer/vue2.6-full` or the Web Component IIFE package. ## Historical Package [#historical-package] `@flyfish-group/file-viewer` remains the compatibility line for Vue 2.7. New projects should prefer `@file-viewer/vue2.7` or `@file-viewer/vue2.6`. --- # Vue 3 Integration (/guide/quickstart-vue3) ## Install [#install] ```bash npm install @file-viewer/vue3 @file-viewer/preset-office ``` Switch `@file-viewer/preset-office` to `@file-viewer/preset-all` when you want the complete official demo capability in one install. ```bash npm install @file-viewer/vue3 @file-viewer/preset-all ``` Use the full package when you want one package to enable the complete matrix by default: ```bash npm install @file-viewer/vue3-full ``` ```ts import { createApp } from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue3-full' createApp(App).use(FileViewer).mount('#app') ``` ```vue ``` ## Dialogs And Component Teardown [#dialogs-and-component-teardown] The Vue 3 component can be mounted inside Element Plus dialogs, drawers, route tabs, and `v-if` blocks. When a dialog should release the active document after closing, let the host actually unmount the component. For Element Plus, use `destroy-on-close`: ```vue ``` On Vue unmount, the component automatically cancels active loading, destroys the current renderer session, clears the rendered DOM, stops zoom and view-state observers, and emits `unload-complete` with `reason: "component-unmount"`. Host code does not need to clear the inner container manually. If the dialog only hides the component, for example with `v-show` or without `destroy-on-close`, the viewer instance stays alive and keeps the current document. That is useful when the product wants to preserve reading position. For explicit teardown while keeping the surrounding component alive, call `viewerRef.value?.destroy()` and recreate the viewer component when previewing again. ## Universal Renderer Assembly [#universal-renderer-assembly] The Vue package stays lightweight. Concrete PDF, Office, CAD, Typst, archive, and engineering capabilities are injected through presets or renderer packages. This path works in Vite, Webpack, Rspack, Rollup, Umi, and internal component libraries: ```ts import officePreset from '@file-viewer/preset-office' const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', styleIsolation: 'shadow', toolbar: { position: 'bottom-right' } } ``` Vue 3 uses Shadow DOM by default so uncontrolled global CSS, low-code resets, and micro-frontend styles cannot break the viewer. Use `styleIsolation:'none'` only for legacy deep class overrides. See [Style Isolation And Customization](/guide/style-isolation) for CSS tokens and `::part()` customization. ## Register Globally [#register-globally] ```ts import { createApp } from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue3' createApp(App).use(FileViewer).mount('#app') ``` ```vue ``` ## Local Registration [#local-registration] ```vue ``` ## Vite Zero-Config Setup [#vite-zero-config-setup] Vite projects can add the plugin to assemble renderer imports and copy Worker/WASM assets automatically. Installing the npm package alone does not make Vite run it; register the plugin once in `vite.config.ts`. The plugin discovers installed preset packages, so application code can omit the manual preset import: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true // Installed @file-viewer/preset-* packages are discovered automatically. }) ] }) ``` When `@file-viewer/vue3-full` is installed, this same configuration recognizes it and publishes the complete matching asset payload in dev and build. The Full package already includes `preset-all`; application code must not install or pass another preset. Vue CLI, Webpack, Rspack, Rollup, and other non-Vite projects run the included same-version CLI instead: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` Use `preset:'auto'` or `autoPresets:true` when `scan:true` is also enabled, so installed presets stay auto-activated while source hints add extra formats. ## Compatibility Names [#compatibility-names] Historical packages remain synchronized: * `@flyfish-group/file-viewer3` * `file-viewer3` New Vue 3 projects should use `@file-viewer/vue3`. --- # Vanilla JS / Script Tag (/guide/quickstart-web) ## Install [#install] ```bash npm install @file-viewer/web @file-viewer/preset-office ``` Use the full package when you want the complete matrix immediately: ```bash npm install @file-viewer/web-full ``` `@file-viewer/web-full` enables the complete format matrix while keeping ``, `mountViewer`, and the same controller APIs. Its CDN / IIFE entry only loads the shell and lazy full preset up front; heavy PDF, Word, Excel, CAD, Typst, archive, and similar renderer bundles are fetched later from `dist/renderers/*.iife.js` when the active file type needs them. The Full package already includes `preset-all`; do not install or pass another preset. Direct CDN use, or deploying its complete `dist/` directory intact, includes renderer chunks plus Worker/WASM/font/vendor assets and needs no copy command. If a package-aware build emits only the application entry, Vite uses `copyAssets:true`; non-Vite builds use the included same-version CLI shown below. The historical package name remains synchronized for compatibility: ```bash npm install @flyfish-group/file-viewer-web ``` ## RequireJS (AMD) [#requirejs-amd] From 3.0.3, Web and Web Full include a separate `.amd.js` entry. Deploy the complete `@file-viewer/web-full/dist/` directory to your own `/file-viewer/` path, alongside your locally hosted RequireJS. No bundler, `shim`, remote CDN, or global `define` override is needed: ```html
``` Leave `.js` off RequireJS `paths`. Module aliases are your choice. Keep `renderers/`, `vendor/`, and `wasm/` next to the entry: they load lazily from that directory, also under a deployment subpath. The light `flyfish-file-viewer-web.amd.js` exports the same shell API but does not include Full renderers. Existing `.iife.js` script-tag and ESM entries are unchanged; do not load an IIFE as an AMD module. ## Web Component [#web-component] ```html ``` ```ts import { defineFileViewerElement } from '@file-viewer/web' import officePreset from '@file-viewer/preset-office' defineFileViewerElement() const viewer = document.getElementById('viewer') as HTMLElement & { options: unknown } viewer.options = { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' } } ``` Keep the host element or parent container at a stable height. The viewer fills that surface. ## Style Isolation And Theme Customization [#style-isolation-and-theme-customization] ``, `@file-viewer/web-full`, and IIFE entries use Shadow DOM by default to isolate the viewer shell, toolbar, and rendered content. This is the recommended path when the host page has global resets, low-code styles, micro-frontend CSS collisions, or legacy admin CSS. To return to the historical light-DOM behavior, set `style-isolation="none"` explicitly: ```html ``` Use CSS tokens and Shadow Parts for controlled customization: ```css flyfish-file-viewer { --file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96); --file-viewer-button-color: #154b83; } flyfish-file-viewer::part(toolbar) { border-radius: 999px; } ``` See [Style Isolation And Customization](/guide/style-isolation) for modes, tokens, parts, and hostile CSS verification. For Vite projects, add `@file-viewer/vite-plugin`. Installing the package alone does not make Vite run it; register the plugin once in `vite.config.ts`. It auto-discovers installed `@file-viewer/preset-*` packages and injects renderers, so both the Custom Element and `mountViewer` receive the matching format capabilities without manually importing the preset: ```bash npm install -D @file-viewer/vite-plugin ``` ```ts import { defineConfig } from 'vite' import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default defineConfig({ plugins: [ fileViewerRenderers({ copyAssets: true }) ] }) ``` Installing only `@file-viewer/web` gives you the lightest native web component. Add a preset or renderer package for PDF, Office, CAD, Typst, archives, and other concrete formats. Heavy users can use the full package or keep the standard package with `preset-all`: ```bash npm install @file-viewer/web @file-viewer/preset-all ``` Use `formats`, `renderers`, `scan:true`, `inject:false`, or `chunkStrategy:'renderer'` only when the product needs exact registry control. The default path stays `fileViewerRenderers({ copyAssets:true })`, with installed presets auto-activated by the plugin. ## Imperative Mount [#imperative-mount] ### Angular With A Deployment Subpath [#angular-with-a-deployment-subpath] Use the same Web API from `ngAfterViewInit`, and call `controller.destroy()` in `ngOnDestroy`. Angular's application builder does not reliably emit Worker files referenced by dependency JavaScript. With light packages, install `file-viewer-copy-assets` as a development dependency at the same version as the viewer packages. Full packages already include this CLI. Copy the installed resources before `ng build`: ```bash npx --yes file-viewer-copy-assets public/file-viewer ``` Keep the generated `flyfish-viewer-assets.json` with those files. Include the `public` directory in the build's existing asset configuration, for example: ```json { "baseHref": "/ui/", "assets": [{ "glob": "**/*", "input": "public", "output": "/" }] } ``` PPTX discovers its copied Worker relative to the application base, including `/ui/file-viewer/vendor/pptx/pptx.worker.js`; no `deployUrl`, optimizer exclusion, application alias or custom Worker factory is needed. An explicit `presentation.workerUrl` still takes precedence. A missing manifest is a broken asset deployment, not a supported Angular fallback; the renderer reports it instead of requesting a guessed `/ui/worker/pptx.worker.js` path. The maintained example is `apps/component-demo/test/angular-pptx`. Its browser regression cold-installs packages and checks real slides and Worker MIME in development and production; it does not replace Worker with a recorder. ### Mount And Clean Up [#mount-and-clean-up] ```ts import { mountViewer } from '@file-viewer/web' import officePreset from '@file-viewer/preset-office' const controller = mountViewer(document.getElementById('viewer')!, { url: '/files/report.docx', options: { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' }, archive: { cache: true } }, onEvent(event) { console.log(event.type, event.payload) } }) controller.reload() ``` Use `controller.update(options)` to change the source or runtime options. When the source input is unchanged, it keeps the current document mounted; call `controller.reload()` when a fresh render is explicitly required. With the full package, imperative code does not need to import a preset: ```ts import { mountViewer } from '@file-viewer/web-full' const controller = mountViewer(document.getElementById('viewer')!, { url: '/files/demo.dwg', options: { theme: 'light', toolbar: { position: 'bottom-right' } } }) controller.zoomIn() ``` Renderers with continuous zoom also accept Ctrl/⌘ + wheel and two-finger pinch. Set `options.zoomGestures: false` to disable them; the same zoom permissions and operation hooks apply to gestures and toolbar buttons. ## Authenticated Files [#authenticated-files] When the business system must authenticate first, fetch the file in the host page and pass a named `File`: ```ts const blob = await fetch('/api/files/contract', { credentials: 'include' }).then(response => response.blob()) const file = new File([blob], 'contract.pdf', { type: blob.type }) document.querySelector('flyfish-file-viewer')!.file = file ``` ## Script Tag Without A Bundler [#script-tag-without-a-bundler] Use the IIFE bundle for pages that do not run Vite, Webpack, Rspack, Rollup, or another package-aware bundler: ```bash cp ./node_modules/@file-viewer/web/dist/flyfish-file-viewer-web.iife.js ./public/vendor/file-viewer-web/flyfish-file-viewer-web.iife.js ``` ```html ``` The IIFE registers the default custom element and exposes `window.FlyfishFileViewerWeb.mountViewer(container, options)`. ### CDN Full Bundle [#cdn-full-bundle] For no-build pages that need the complete format matrix without local installation, use the `@file-viewer/web-full` CDN entry. jsDelivr / unpkg distribute the complete IIFE directly from npm and expose `window.FlyfishFileViewerWebFull`. The first script only loads the shell and lazy full preset; PDF, Word, Excel, CAD, Typst, archive, and similar renderers are fetched later from `dist/renderers/*.iife.js` when the active file type needs them. Worker, WASM, font, and vendor assets still resolve relative to the script URL: ```html
``` The Custom Element route uses the same full bundle: ```html ``` The CDN full bundle is ideal for POCs, classic admin pages, and public production pages that want complete capability quickly. For intranet, strict-CSP, fully offline, or private Cloudflare / cdnjs-style static domains, mirror `@file-viewer/web-full/dist` or the assets generated by `file-viewer-copy-assets` to your own CDN. cdnjs.com does not automatically host arbitrary npm packages, so a cdnjs URL only exists after the library is accepted there. ## Offline Assets [#offline-assets] For intranet or strict-CSP deployments, copy runtime assets into your own public directory: ```bash # @file-viewer/web-full (same-version CLI included) npx --no-install file-viewer-copy-assets ./public/file-viewer # Standard @file-viewer/web deployment npx --yes file-viewer-copy-assets ./public/file-viewer ``` Run one matching command only for an entry-only or non-Vite npm build; an intact `web-full/dist/` deployment already contains the same payload. The command verifies worker, WASM, PDF, CAD, Typst, Archive, Data, DOCX, Spreadsheet, PPTX, and Draw\.io assets. Runtime options such as `options.pdf.workerUrl`, `options.presentation.workerUrl`, `options.archive.wasmUrl`, `options.docx.workerUrl`, `options.typst.compilerWasmUrl`, and `options.drawing.viewerScriptUrl` can point to self-hosted URLs. ## Internationalization [#internationalization] The Web Component accepts `locale` as an HTML attribute or JS property. Use `options.messages` / `options.i18n` for custom copy: ```html ``` ```ts const viewer = document.querySelector('flyfish-file-viewer')! viewer.locale = 'zh-CN' viewer.options = { i18n: { locale: 'zh-CN', messages: { 'toolbar.print': 'Print document' } } } ``` --- # Quickstart (/guide/quickstart) ## Five-step Integration [#five-step-integration] | Step | Decision | Fast answer | | ---- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 1 | Pick the component package | Use standard packages such as `@file-viewer/web`, `@file-viewer/vue3`, or `@file-viewer/react` for the lightest entry; Full packages preserve the published compatibility matrix, while later specialist renderers remain explicit. | | 2 | Pick the capability layer | Standard packages receive `preset-lite`, `preset-office`, `preset-engineering`, or `preset-all` through options; Full packages enable the published compatibility matrix, while later specialist renderers remain explicit additions. | | 3 | Publish runtime assets | Full packages use `copyAssets:true` with Vite; other build tools run `npx --no-install file-viewer-copy-assets ./public/file-viewer` so every selected capability has its matching Worker/WASM assets. | | 4 | Pass the source and options | Use `url="/files/demo.pdf"` or a real `File`; standard packages pass a preset through `options`, while full packages can start with theme, toolbar, watermark, and business options only. | | 5 | Confirm style isolation | Every standard component defaults to Shadow DOM. Customize with tokens / `::part()` and use `options.styleIsolation:'none'` only for legacy deep overrides. | This page keeps the shortest runnable paths. See [Component Options](/guide/usage) for the full API, renderer package matrix, toolbar, watermark, print, search, lifecycle, and guard options. See [Style Isolation And Customization](/guide/style-isolation) for Shadow DOM, tokens, and parts. See [Modular Assembly](/guide/on-demand-renderers) for on-demand renderers and the Vite plugin.
Mobile note: for H5 and mobile browsers, give the viewer host a stable height such as height:100dvh; min-height:0, and prefer toolbar.position:'bottom-right'. React Native should load a WebView-based H5 viewer route; the DOM component cannot mount directly into native RN views. See the React mobile example.
## Pick The Capability Layer First [#pick-the-capability-layer-first] Installing a standard component package such as `@file-viewer/vue3`, `@file-viewer/react`, or `@file-viewer/web` is the lightest path. It gives you the native framework component, types, controller APIs, and the core foundation; it does not install every heavy PDF, Office, CAD, Typst, archive, or engineering renderer by default. If you want to validate the complete official demo capability first, use a full package. Full packages already include `@file-viewer/preset-all`; do not install or pass another preset. Complete npm support also includes matching Worker, WASM, font, and vendor assets: Vite publishes them automatically, while other build tools run the same-version CLI included by every full package. For CDN / script-tag pages, prefer `@file-viewer/web-full`: direct jsDelivr/unpkg usage, or an intact mirror of the complete `dist/` directory, resolves every asset relative to the script URL and needs no copy command. | Mode | Install | Notes | | ---------------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- | | Light standard package | `npm i @file-viewer/vue3 @file-viewer/preset-office` | Pick exactly the preset / renderer your product needs | | Complete full package | `npm i @file-viewer/vue3-full` | Includes `preset-all`; publish runtime assets under `/file-viewer/` for complete support | | CDN full | `https://unpkg.com/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js` | No local install, ideal for script-tag validation | Add a preset or a single renderer package for the file formats your product actually needs: | Package | Coverage | Best fit | | --------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------- | | `@file-viewer/preset-lite` | Text, Markdown, code, image, audio, video | Lightweight attachment preview | | `@file-viewer/preset-office` | PDF, Word, Excel, PowerPoint, OFD, RTF, OpenDocument | OA, approvals, knowledge bases, contracts | | `@file-viewer/preset-engineering` | CAD, 3D, drawing, XMind, Geo, Typst, Archive, Data, EDA | Engineering, R\&D, design assets | | `@file-viewer/preset-all` | Full official demo matrix | Demos and internal all-format workbenches | | Single renderer | For example `@file-viewer/renderer-pdf` or `@file-viewer/renderer-word` | Minimal custom format cuts | The most stable integration path is to import a preset or renderer explicitly and pass it through `options.preset` / `options.renderers`. This works in Webpack, Rspack, Rollup, Umi, classic multi-page apps, micro-frontends, and internal component libraries. Vite projects can add `@file-viewer/vite-plugin` later to remove manual imports and copy offline assets automatically. ### Universal Setup: Inject options.preset [#universal-setup-inject-optionspreset] Install the component package and one preset: ```bash pnpm add @file-viewer/vue3 @file-viewer/preset-office ``` ```ts import officePreset from '@file-viewer/preset-office' export const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' } } ``` Pass the same options object to your framework component: ```vue ``` Multiple capability bundles use the same `preset` field as an array, so applications do not need a second option name: ```ts import officePreset from '@file-viewer/preset-office' import engineeringPreset from '@file-viewer/preset-engineering' export const viewerOptions = { preset: [officePreset, engineeringPreset], rendererMode: 'replace' } ``` For the smallest exact cut, skip presets and install a single renderer: ```bash pnpm add @file-viewer/vue3 @file-viewer/renderer-pdf ``` ```ts import { pdfRenderer } from '@file-viewer/renderer-pdf' export const viewerOptions = { renderers: [pdfRenderer], rendererMode: 'replace' } ``` If a file extension is supported but the required renderer is not assembled, the viewer shows an install-oriented hint instead of a vague unsupported state. ### Complete Setup: Full Packages [#complete-setup-full-packages] Full packages are for teams that want the complete format experience first and can optimize package size later. They expose the same props, events, controller APIs, and options as standard packages, with `preset-all` built in and enabled by default. Do not install another preset: | Ecosystem | Full package | Standard package | | -------------------------- | -------------------------------- | --------------------------- | | Vanilla JS / Web Component | `@file-viewer/web-full` | `@file-viewer/web` | | Vue 3 | `@file-viewer/vue3-full` | `@file-viewer/vue3` | | Vue 2.7 | `@file-viewer/vue2.7-full` | `@file-viewer/vue2.7` | | Vue 2.6 | `@file-viewer/vue2.6-full` | `@file-viewer/vue2.6` | | React 18 / 19 | `@file-viewer/react-full` | `@file-viewer/react` | | React 16.8 / 17 | `@file-viewer/react-legacy-full` | `@file-viewer/react-legacy` | | jQuery | `@file-viewer/jquery-full` | `@file-viewer/jquery` | | Svelte | `@file-viewer/svelte-full` | `@file-viewer/svelte` | ```bash npm install @file-viewer/vue3-full ``` ```vue ``` Each framework keeps its native integration API; do not copy the Vue component syntax across stacks: ```ts // Vue 2.7; use @file-viewer/vue2.6-full with Vue 2.6. import Vue from 'vue' import FileViewerPlugin from '@file-viewer/vue2.7-full' Vue.use(FileViewerPlugin) ``` ```tsx import FileViewer from '@file-viewer/react-full' export const Preview = () => ``` ```svelte ``` ```ts import $ from 'jquery' import installFileViewer from '@file-viewer/jquery-full' installFileViewer($) $('#viewer').fileViewer({ url: '/files/contract.pdf' }) ``` Every full package defaults its runtime asset base to `file-viewer/` under the deployment base (`/file-viewer/` at the origin root) and pre-fills Archive, PDF, DOCX, Excel, PPTX, CAD, Typst, Draw\.io, and SQLite asset URLs. Vite projects register the plugin once to publish complete assets in development and production: ```ts import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default { plugins: [fileViewerRenderers({ copyAssets: true })] } ``` Webpack, Rspack, Rollup, Vue CLI, Umi, and classic multi-page projects run the same-version CLI included by the full package: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` The complete `web-full` `dist/` already carries assets and can be deployed without this command; entry-only builds run the included CLI. Without `file-viewer/` under the deployment base, lightweight formats and a few compatibility paths may still work, but CAD, Typst, RAR/7z/encrypted archives, Draw\.io, SQLite, PDF CMaps/fonts, and similar pipelines are not complete. If your static prefix is different, set the default base once during application startup: ```ts import { setDefaultFullAssetBaseUrl } from '@file-viewer/vue3-full' setDefaultFullAssetBaseUrl('/static/file-viewer/') ``` Explicit options such as `options.archive.workerUrl` or `options.pdf.workerUrl` still win, which keeps tenant-specific or staged static paths easy to override. ### CDN Full: Complete Script-Tag Trial [#cdn-full-complete-script-tag-trial] No-build pages can load the full CDN bundle directly. Direct jsDelivr/unpkg usage, or an intact deployment of the complete `dist/` directory under one static prefix, needs no asset copy command. Copying only the entry IIFE is not a complete deployment. ```html
``` The Custom Element route is available as well: ```html ``` ### Vite Plugin: Zero-Config Assembly [#vite-plugin-zero-config-assembly] In Vite projects, standard component packages install one `@file-viewer/preset-*`; full packages already include `preset-all`. Once `fileViewerRenderers({ copyAssets:true })` is registered, it recognizes the installed full package or preset. Full assets publish under `/file-viewer/`; standard packages/presets keep their existing root placement. Application code does not import another preset: ```bash pnpm add @file-viewer/vue3 @file-viewer/preset-office pnpm add -D @file-viewer/vite-plugin ``` ```ts // vite.config.ts import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default { plugins: [ fileViewerRenderers({ copyAssets: true // No preset:'office' needed; the plugin discovers installed @file-viewer/preset-office. }) ] } ``` For complete capability, switch to a full package and remove the separate preset: ```bash pnpm add @file-viewer/vue3-full pnpm add -D @file-viewer/vite-plugin ``` Use explicit options only when you need customization: | Option | Best fit | | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `copyAssets:true` | Recognizes full packages / presets; full packages publish under `/file-viewer/` in dev and production, while standard packages/presets keep root placement; required for full packages | | `formats` / `renderers` | Generates exact renderer imports when you do not use a preset, or when a preset needs a few extra formats | | `scan:true` | Scans source hints such as `fileViewerFormats`, `data-file-viewer-formats`, and upload `accept` attributes | | `preset:'auto'` / `autoPresets:true` | Keeps installed preset auto-discovery active while `scan:true` is enabled | | `inject:false` | Disables auto injection so you can import `virtual:file-viewer-renderers` and pass `options.renderers` manually | | `chunkStrategy:'renderer'` | Splits chunks by renderer for caching, debugging, and heavy-pipeline size analysis | The recommended default is `fileViewerRenderers({ copyAssets:true })`. Configure the advanced options only for strict bundle cuts, source-hint scanning, or complete registry control. ## Vanilla JavaScript / Web Component [#vanilla-javascript--web-component] ```bash npm install @file-viewer/web @file-viewer/preset-office ``` ```html ``` ```ts import { defineFileViewerElement } from '@file-viewer/web' import officePreset from '@file-viewer/preset-office' defineFileViewerElement() const viewer = document.getElementById('viewer') viewer.options = { preset: officePreset, rendererMode: 'replace', theme: 'light', toolbar: { position: 'bottom-right' } } ``` ## Vue 3 [#vue-3] ```bash npm install @file-viewer/vue3 @file-viewer/preset-office ``` ```ts import { createApp } from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue3' createApp(App).use(FileViewer).mount('#app') ``` ```vue ``` ## React [#react] ```bash npm install @file-viewer/react @file-viewer/preset-office ``` ```tsx import FileViewer from '@file-viewer/react' import officePreset from '@file-viewer/preset-office' export function Preview() { return (
) } ``` React 16.8/17 projects can use `@file-viewer/react-legacy`. ## Locale And Copy [#locale-and-copy] The viewer defaults to `locale: 'auto'`, which follows the browser language and resolves to Chinese or English. Use the same `options` object across Vanilla JS / Pure Web, Vue, React, jQuery, and Svelte when you need a fixed locale or custom copy: ```ts const options = { locale: 'en-US', messages: { 'toolbar.download': 'Save file' } } ``` You can also group locale and copy under `i18n`: ```ts const options = { i18n: { locale: 'zh-CN', messages(key, params, locale) { return key === 'state.empty.title' ? '请选择文件' : undefined } } } ``` Web Component users can set `locale="en-US"` directly on ``. You can read the complete `FileViewerMessageKey` mapping from core. The exported object is the same copy source used at runtime, so it is the safest way to generate translation sheets, coverage checks, or custom-copy tests for the installed version: ```ts import { FILE_VIEWER_BUILTIN_MESSAGES, type FileViewerMessageKey } from '@file-viewer/core' const rows: Array<{ key: FileViewerMessageKey zhCN: string enUS: string }> = Object.keys(FILE_VIEWER_BUILTIN_MESSAGES['zh-CN']).map(key => ({ key: key as FileViewerMessageKey, zhCN: FILE_VIEWER_BUILTIN_MESSAGES['zh-CN'][key as FileViewerMessageKey], enUS: FILE_VIEWER_BUILTIN_MESSAGES['en-US'][key as FileViewerMessageKey] })) ``` `messages` only needs the keys you want to override. Missing keys continue to use the built-in copy for the active `locale`. Loading states, error states, toolbar controls, PDF / Office / OFD / archive surfaces, and standard renderer notices all follow the same `options.locale` / `options.i18n` path. ## Authenticated Files [#authenticated-files] If your app must authenticate before downloading a file, fetch the file in the host app and pass a named `File` to the viewer: ```ts const blob = await fetch('/api/files/contract', { credentials: 'include' }).then(response => response.blob()) const file = new File([blob], 'contract.pdf', { type: blob.type }) ``` Passing a filename with an extension is important because the viewer uses it to pick the renderer. ## Full-Package Worker And WASM Assets [#full-package-worker-and-wasm-assets] The renderer matrix alone is not the complete full-package contract. Non-Vite full packages run their included same-version CLI and serve the output from `file-viewer/` under the deployment base: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer ``` `web-full` may instead deploy its complete `dist/`, which already contains the assets. The command verifies PDF, archive, DOCX, spreadsheet, Draw\.io, CAD, Typst, SQLite, Worker, WASM, font, and vendor assets and writes `flyfish-viewer-assets.json`. Use `setDefaultFullAssetBaseUrl()` only when the public URL differs. Direct CDN `web-full`, or an intact mirror of its complete `dist/`, is the no-copy exception. ## Zero-Dependency Integration: Official Demo iframe [#zero-dependency-integration-official-demo-iframe] If a customer system only needs preview capability and should not install npm packages or change its build pipeline, use the official demo build output directly. Download `file-viewer-v2-*-official-demo-iframe.tar.gz` from GitHub Releases, extract it to one static directory such as `/file-viewer/`, and keep `assets/`, `vendor/`, `wasm/`, and `example/` together. The simplest URL-based preview: ```html ``` If the parent page must fetch an authenticated file first, pass the resulting `Blob` to the demo: ```html ``` `from` must equal the parent page origin. The demo accepts only a `Blob` from that origin. Prefer `/iframe.html` for the chrome-free entry, or `/iframe` on static hosts that support clean URLs. The original `/index.html` demo entry keeps the same `url`, `from`, `name`, and `postMessage(Blob)` protocol for existing customer integrations. ## Try The Demo Locally [#try-the-demo-locally] ```bash pnpm install pnpm dev ``` The main demo opens at the Vite dev server URL. The zero-dependency iframe entry is available at `/iframe.html`, and the comparison demo is available at `/compare.html`. ### Japanese locale [#japanese-locale] Use `locale: 'ja-JP'` to force Japanese. The default `auto` mode checks the complete `navigator.languages` preference list and selects Japanese for `ja`, `ja-JP`, and other Japanese language tags. Unsupported browser locales fall back to English. ### German locale [#german-locale] Use `locale: 'de-DE'` to force German. The default `auto` mode checks the complete `navigator.languages` preference list and selects German for `de`, `de-DE`, and other German language tags. Unsupported browser locales fall back to English. --- # Style Isolation And Customization (/guide/style-isolation) This model is designed for admin systems, OA portals, low-code platforms, micro-frontends, embedded third-party pages, and products where host CSS is hard to control. The goal is to keep both guarantees at once: aggressive host styles should not break the viewer, while product teams can still customize theme, toolbar, and key surfaces predictably. ## Recommendation [#recommendation] | Scenario | Recommended path | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | New projects, classic admin pages, script tags, low-code, micro-frontends | Use the component package for your stack. The default `styleIsolation:'auto'` uses Shadow DOM. | | Vue / React / Svelte / jQuery projects under aggressive host CSS | No extra option is required; their standard packages use the same Shadow DOM boundary. | | Need controlled inheritance from host fonts or theme variables | Use `styleIsolation:'scoped'`. | | Legacy projects with deep internal class overrides | Temporarily use `styleIsolation:'none'`, then migrate to tokens and parts. | iframe is not the recommended core path. It gives stronger process-like isolation, but makes file transfer, printing, search, sizing, event bridges, and offline asset deployment much more complex. File Viewer prefers platform-native Shadow DOM isolation. ## Public API [#public-api] `FileViewerOptions` exposes one shared field: ```ts type FileViewerStyleIsolation = 'auto' | 'shadow' | 'scoped' | 'none' const options = { styleIsolation: 'shadow', theme: 'light', toolbar: { position: 'bottom-right' } } ``` | Value | Behavior | | -------- | ------------------------------------------------------------------------------------------------------------------------- | | `auto` | Default. Web Component, IIFE, Vue, React, Svelte, jQuery, and full packages use Shadow DOM. | | `shadow` | Creates a ShadowRoot render surface. Styles are injected into the isolated root first, and overlays prefer the same root. | | `scoped` | Does not create a ShadowRoot. Uses a stable root selector and local resets to limit its impact. | | `none` | Historical light-DOM behavior for legacy theme CSS or deep overrides. | The Web Component also supports an attribute: ```html ``` To return to historical behavior: ```html ``` ## CSS Tokens [#css-tokens] Start customization with `--file-viewer-*` CSS variables. They can be placed on the custom element, a business shell, `:root`, or a theme class. Shadow DOM inherits CSS custom properties from the host. ```css flyfish-file-viewer { --file-viewer-bg: #f7f9fc; --file-viewer-text: #172033; --file-viewer-font: Inter, "Segoe UI", sans-serif; --file-viewer-toolbar-bg: rgba(255, 255, 255, 0.96); --file-viewer-toolbar-border: rgba(21, 75, 131, 0.16); --file-viewer-button-color: #154b83; --file-viewer-button-hover-bg: rgba(21, 75, 131, 0.08); --file-viewer-button-radius: 6px; } ``` | Token | Purpose | | --------------------------------------------------------------------------------------------------------- | ---------------------------------------------- | | `--file-viewer-bg` / `--file-viewer-text` / `--file-viewer-muted` | Shell background, primary text, and muted text | | `--file-viewer-font` | Viewer shell, toolbar, and state panel font | | `--file-viewer-border` / `--file-viewer-focus-ring` | Borders and keyboard focus styles | | `--file-viewer-toolbar-bg` / `--file-viewer-toolbar-border` / `--file-viewer-toolbar-shadow` | Toolbar background, border, and shadow | | `--file-viewer-toolbar-padding` / `--file-viewer-toolbar-gap` / `--file-viewer-toolbar-radius` | Toolbar spacing and radius | | `--file-viewer-toolbar-floating-offset` / `--file-viewer-toolbar-floating-padding` | Floating toolbar offset and safe padding | | `--file-viewer-group-bg` / `--file-viewer-group-border` | Toolbar group background and border | | `--file-viewer-button-color` / `--file-viewer-button-hover-color` / `--file-viewer-button-disabled-color` | Button text colors | | `--file-viewer-button-hover-bg` / `--file-viewer-button-radius` | Button hover background and radius | | `--file-viewer-input-bg` / `--file-viewer-input-color` | Built-in inputs such as search | | `--file-viewer-z-toolbar` / `--file-viewer-z-floating-toolbar` | Toolbar stacking levels | ## Shadow Parts [#shadow-parts] When tokens are not enough, target stable surfaces with `::part()`: ```css flyfish-file-viewer::part(toolbar) { border-radius: 999px; } flyfish-file-viewer::part(button) { min-width: 32px; font-weight: 600; } flyfish-file-viewer::part(content) { background: #eef2f7; } ``` | Part | Current purpose | | ---------------- | --------------------------------- | | `host` | Internal Web Component mount node | | `shell` | Viewer shell | | `toolbar` | Built-in toolbar container | | `toolbar-group` | Toolbar button group | | `toolbar-status` | Toolbar status text | | `button` | Built-in buttons | | `input` | Built-in inputs such as search | | `content` | Renderer content mount area | Renderer authors and future extensions should keep using stable names such as `state-panel` and `watermark` when exposing state panels and watermark layers. Application code should not rely on `.file-viewer-*` internal classes because those classes are implementation details. ## Framework Packages [#framework-packages] Vue / React / Svelte / jQuery use the same Shadow DOM boundary by default. The explicit option below is equivalent to `auto` and can be useful when an application wants to lock the policy: ```ts const viewerOptions = { styleIsolation: 'shadow', preset: officePreset, rendererMode: 'replace', theme: 'light' } ``` If the application needs limited inheritance from host CSS without letting global resets pollute document content, use: ```ts const viewerOptions = { styleIsolation: 'scoped' } ``` ## Hostile CSS Harness [#hostile-css-harness] Before release, add an aggressive host-CSS harness once and confirm toolbar, buttons, document content, images, canvases, tables, and SVGs remain usable: ```css * { box-sizing: content-box !important; font-size: 26px !important; line-height: 3 !important; } button, input, table, img, svg, canvas, a, div { all: unset !important; display: block !important; border: 8px solid red !important; } ``` Expected behavior: * With `styleIsolation:'auto'` or `'shadow'`, the standard component toolbar and content stay usable. * Theme variables set through `--file-viewer-*` still apply. * `flyfish-file-viewer::part(toolbar)` and similar selectors customize only the intended surface. * Web Component DOM events remain `bubbles:true` and `composed:true`; framework packages continue to forward their native component events across the Shadow boundary. ## Printing And Export [#printing-and-export] Under Shadow DOM, print and HTML export collect content and required styles from the current render surface. Format-specific adapters still take precedence for complete-page output, such as PDF and Word. Unreliable pipelines such as virtual spreadsheets, media, and 3D continue to hide print buttons dynamically. If you maintain a custom renderer: * Do not inject preview styles into `document.head` or `document.body`. * Prefer the core render surface and style injection helper. * Mount lightboxes, menus, and overlays inside `context.surface.shadowRoot` or the current renderer container. * Use stable `part` names for public customization surfaces instead of exposing temporary classes as API. ## Migration [#migration] 1. Keep the default `auto` for new integrations across all standard component packages. 2. If a legacy project depends on deep class overrides, start with `styleIsolation:'none'`. 3. Move color, font, spacing, and radius overrides to `--file-viewer-*` tokens. 4. Move structural customization to `::part()`. 5. Switch back to `auto` or explicit `shadow`, then run the hostile CSS harness and common-format smoke tests. --- # Component Options (/guide/usage) ## Minimal Options Shape [#minimal-options-shape] Standard component packages stay lightweight. Install a component package for your stack, then assemble concrete file-format capability through `options.preset` or `options.renderers`. ```ts import officePreset from '@file-viewer/preset-office' export const viewerOptions = { preset: officePreset, rendererMode: 'replace', theme: 'light', styleIsolation: 'shadow', ui: { density: 'compact' }, toolbar: { position: 'bottom-right', download: true, print: true, exportHtml: true, zoom: true }, watermark: { text: 'Internal', opacity: 0.14 }, search: { maxMatches: 1000, caseSensitive: false }, archive: { cache: true, workerTimeoutMs: 30000, entryActions: { download(entry) { return entry.path.startsWith('public/') } } }, pdf: { toolbar: true, streaming: 'same-origin' } } ``` `builtinRenderers` remains available for advanced baseline control and historical compatibility, but normal integrations should start with `preset` or `renderers`. ## Preflight Before Rendering [#preflight-before-rendering] Call `precheckFileViewerSource()` after file selection when the product must reject an unsupported or obviously malformed file before mounting a viewer. It checks extension capability and validates known PDF, OpenXML / OpenDocument, legacy OLE Office, and RTF signatures or package parts without loading a renderer. ```ts import { precheckFileViewerSource } from '@file-viewer/core/headless' const result = await precheckFileViewerSource(file, { supportedExtensions: ['pdf', 'docx', 'xlsx', 'pptx'] }) if (!result.previewable) { console.warn(result.status, result.reason, result.missingParts) } ``` `supported` describes the supplied capability list; `valid` describes the content check. `valid: null` means the format has no lightweight validator or only a URL was supplied, not that a full parse passed. The renderer remains the final authority for malformed content. Blob-backed ZIP/Office files read only ZIP metadata instead of copying the complete file. ## Common Options [#common-options] | Option area | Purpose | | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `theme` | Viewer theme: `light`, `dark`, or `system`. Default is `system`; pass `light` when embedding in a fixed light business UI. | | `styleIsolation` | Style isolation mode: `auto`, `shadow`, `scoped`, or `none`. With `auto`, every standard component uses Shadow DOM so host CSS cannot break the viewer. Customize with `--file-viewer-*` tokens plus `::part()`; use `none` only for legacy deep overrides. See [Style Isolation And Customization](/guide/style-isolation). | | `ui.density` | UI chrome density: `comfortable` or `compact`. The default `comfortable` keeps existing spacing; `compact` tightens toolbars, archive lists, nested preview headers, badges, small buttons, and search inputs while keeping document content readable. | | `preset` | Bundler-neutral preset assembly. Pass the default export from `@file-viewer/preset-lite`, `@file-viewer/preset-office`, `@file-viewer/preset-engineering`, or `@file-viewer/preset-all`; compose with `preset: [officePreset, engineeringPreset]`. `presets` is kept only as a compatibility alias for early 2.x drafts. | | `renderers` / `rendererMode` | Exact renderer or custom renderer assembly. `rendererMode:'replace'` starts from an empty registry, so `preset` / `renderers` define the active capability set; `extend` appends to the current built-in baseline. | | `builtinRenderers` | Advanced built-in baseline switch: `all`, `lite`, or `none`. Most quick starts do not need it. | | `toolbar` | Built-in operation bar visibility, position, grouped actions, key-based items, permission gates, and button-specific guards. The print control stays a single compact button with a dropdown for **Print now** and **Mask & print**. | | `zoomGestures` | Ctrl/⌘ + wheel and two-finger pinch zoom the document when its renderer supports continuous zoom. Enabled by default; use `false` to disable both, or `{ wheel: false }` / `{ pinch: false }` to disable one. Ordinary scrolling and editable controls retain browser behavior. Gestures respect the same operation permissions and hooks as zoom buttons. | | `watermark` | Text or image watermark source, opacity, spacing, size, rotation, color, and toggle behavior. Enabled watermarks are included in print output. | | `search` | Document search, highlighted matches, next / previous navigation, whole-word and case-sensitive behavior. | | `text` | Set `toolbar: false` to hide the renderer-local metadata bar and `lineNumbers: true` for a copy-safe gutter. `wrapLongLines: true` visually wraps logical lines without changing source bytes and also applies to the bounded large-text view. `prettyPrint: true` lazily formats supported structured text for display with Prettier; a badge and toolbar switch distinguish the formatted representation from the original source. `prettyPrintMaxBytes` limits only formatting and defaults to the effective `virtualizeAboveBytes` value (512 KiB when omitted). Oversized, malformed, or unsupported input falls back without error, after which the existing regular/virtual renderer remains authoritative. Fenced Markdown code is highlighted by its declared language by default; set `markdownHighlight: false` to disable it. Language modules load locally on demand; unknown languages or code beyond the 512 KiB highlighting budget remain source. No `highlightAll()` call is needed inside Shadow DOM. Markdown stays rendered by default; use `markdownVirtualizeAboveBytes` only for exceptionally large source inspection. The legacy `*-full` script-tag IIFE assets do not bundle Prettier, so `prettyPrint` falls back to the original source there. | | `ai` | Text chunk collection for vectorization, source tracing, source-aware highlighting, and audit workflows. It does not call a cloud model by itself. | | `archive` | Safe extraction limits, IndexedDB cache behavior, worker timeout, nested preview, and self-hosted libarchive paths. | | `pdf`, `docx`, `spreadsheet`, `cad`, `typst`, `drawing`, `data`, `binary` | Renderer-specific asset URLs and behavior knobs. | | `cad.showImageExport` | Show the renderer-local PNG/JPEG buttons, default `true`. Hiding them does not change the shared original-file download button; download and HTML-export permission gates still apply. | | `presentation.workerUrl` | Optional explicit PPTX Worker URL. Otherwise the renderer discovers the standard copied asset manifest under the application asset base, then retains the package's development fallback. See [Angular integration](/guide/quickstart-web). | | `hooks` | Load start, load complete, unload start, unload complete, errors, and renderer context callbacks. | | `beforeOperation` | Global pre-action guard for download, print, export HTML, zoom, and custom operations. | ## Preset And Renderer Matrix [#preset-and-renderer-matrix] Presets are product-shaped capability bundles. Individual renderers are exact, minimal imports for products that only need a few formats. | Preset | Included renderers | Typical formats | Best fit | | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `@file-viewer/preset-lite` | `renderer-text`, `renderer-image`, `renderer-media` | Markdown, code, text, image, audio, video, HLS, HEIC | Lightweight attachments, tickets, chat, mobile-first surfaces | | `@file-viewer/preset-office` | `renderer-pdf`, `renderer-word`, `renderer-spreadsheet`, `renderer-presentation`, `renderer-ofd` | PDF, DOC/DOCX/DOT, RTF, ODT, XLS/XLSX/ODS, PPT/PPTX, OFD | OA, approvals, knowledge bases, contracts, archive portals | | `@file-viewer/preset-engineering` | `renderer-cad`, `renderer-3d`, `renderer-drawing`, `renderer-mindmap`, `renderer-geo`, `renderer-typst`, `renderer-archive`, `renderer-data`, `renderer-eda` | DWG/DXF/DWF, 3D, draw\.io, Excalidraw, Mermaid, PlantUML, XMind, GeoJSON/KML/GPX/SHP, Typst, archives, PSD/SQLite/Parquet, OLB/DRA/GDS/OASIS | Engineering drawings, R\&D attachments, design assets, technical archives | | `@file-viewer/preset-all` | Published standard renderer set plus low-cost core browser routes | Full standard matrix | Attachment centers, demos, validation environments that do not need an explicit specialist | Every renderer below can be passed through `options.renderers`: | Renderer package | Export | Pipeline | | ------------------------------------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `@file-viewer/renderer-pdf` | `pdfRenderer` | PDF and PDF-backed AI files | | `@file-viewer/renderer-word` | `wordRenderer` | DOCX, DOC, DOT, RTF, ODT, OpenDocument | | `@file-viewer/renderer-spreadsheet` | `spreadsheetRenderer` | XLSX, XLS, ODS, CSV and spreadsheet-like files | | `@file-viewer/renderer-presentation` | `presentationRenderer` | Binary PPT through `@file-viewer/ppt`; PPTX/PPTM/POTX/POTM/PPSX/PPSM through `@file-viewer/pptx`; both load on demand | | `@file-viewer/renderer-ofd` | `ofdRenderer` | OFD | | `@file-viewer/renderer-cad` | `cadRenderer` | DWG, DXF, DWF, DWFx, XPS | | `@file-viewer/renderer-3d` | `modelRenderer` | GLB, GLTF, OBJ, STL, PLY, FBX, DAE, USD; local OCCT preview for STEP/STP, IGES/IGS, and BREP; explicit specialist subpaths add IFC (`/ifc`) and opt-in streaming Geo3D (`/geo3d`: LAS/LAZ/COPC, GeoTIFF/COG, CityJSON, 3D Tiles, 3TZ) without entering Full presets; 3DM keeps signature and integration guidance | | `@file-viewer/renderer-drawing` | `drawingRenderer` | draw\.io, Excalidraw, Mermaid, PlantUML | | `@file-viewer/renderer-mindmap` | `mindmapRenderer` | XMind | | `@file-viewer/renderer-geo` | `geoRenderer` | GeoJSON, KML, GPX, SHP | | `@file-viewer/renderer-typst` | `typstRenderer` | Typst source rendered through local WASM assets | | `@file-viewer/renderer-archive` | `archiveRenderer` | ZIP, RAR, 7Z, TAR, GZ, ISO, APK, CBZ, CBR and nested previews | | `@file-viewer/renderer-email` | `emailRenderer` | EML, MSG, MBOX | | `@file-viewer/renderer-epub` | `ebookRenderer` | EPUB, UMD | | `@file-viewer/renderer-text` | `textRenderer` | Markdown, code, logs, JSON/YAML, patch, git bundle | | `@file-viewer/renderer-image` | `imageRenderer` | Images, HEIC / HEIF where supported by the renderer | | `@file-viewer/renderer-media` | `mediaRenderer` | Audio, video, HLS, MIDI summaries | | `@file-viewer/renderer-data` | `dataRenderer` | PSD, fonts, SQLite, Parquet, Avro, WASM, WebArchive, AI/EPS summaries | | `@file-viewer/renderer-binary` | `binaryRenderer` | Explicit `.bin`, `.hex`, ELF, PE/COFF, Mach-O, and Java class byte inspection; no MIME wildcard or specialist-route override | | `@file-viewer/renderer-eda` | `edaRenderer` | OLB, DRA, GDS, OAS/OASIS | EML and MSG attachments open through the same resolved renderer registry as the parent viewer. React, React Legacy, Vanilla JS, and Web Component integrations do not need a framework-specific nested-preview bridge. With a lightweight component, include the preset or renderer for each attachment type you want to preview (for example, the PDF renderer for PDF attachments); Full packages already include the complete standard registry. Attachment filenames are rendered as text, not HTML. `@file-viewer/renderer-binary` is intentionally separate from `preset-all` and every Full/Vue 2 closure. Register it with `rendererMode: 'replace'` for a binary-only surface or `extend` alongside a focused preset. Its bounded module Worker defaults to 16 MiB, 5 seconds, 512 nodes, 16 levels, and 4 KiB decoded strings; a raw byte view is the fallback rather than an `application/octet-stream` claim. `@file-viewer/eda-layout`, `@file-viewer/eda-orcad`, `@file-viewer/geometry-engine`, and `@file-viewer/pptx` are reusable engine packages behind renderers. Advanced teams can use them directly, while normal viewer integrations should install the matching renderer or preset. ## Assembly Decisions [#assembly-decisions] | Goal | Recommended setup | | ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | Non-Vite or maximum bundler compatibility | Import a preset and pass `options.preset`. | | Vite app with less application code | Install a preset, register `@file-viewer/vite-plugin`, and use `fileViewerRenderers({ copyAssets:true })`. | | One exact format | Install one renderer and pass `options.renderers: [pdfRenderer]`. | | Office plus engineering documents | Use `preset: [officePreset, engineeringPreset]`. | | Supported extension but missing renderer | The viewer shows which preset / renderer to install. | | Truly unknown extension | The viewer shows an unsupported-format state. | ## Renderer-specific Options [#renderer-specific-options] | Option | Notes | | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `archive.workerUrl` / `archive.wasmUrl` | Self-host libarchive worker / WASM when the default viewer asset location does not match your deployment. | | `archive.workerTimeoutMs` | Timeout for worker startup, encryption checks, and directory reading; the viewer falls back to ZIP/TAR/GZIP-compatible paths when possible. | | `archive.cache` | Enables IndexedDB cache for extracted nested files. | | `archive.maxArchiveSize` / `archive.maxEntryPreviewSize` | Memory and safety limits for archive directory reading and nested preview. | | `archive.entryActions.download` | Controls the download button shown while previewing a file from inside an archive. Pass `false` to hide it globally, or `(entry) => boolean` to decide by path, extension, size, and other metadata. This only affects nested archive entries; the viewer-level original archive download remains controlled by `toolbar` and operation guards. | | `docx.worker` | Auto-detects the safest DOCX parsing path by default: HTTP/HTTPS keeps the worker enabled, while Electron `file://`, `about:`, and `data:` documents fall back to the main thread. Explicit `true` / `false` values still take precedence. | | `docx.workerUrl` / `docx.workerJsZipUrl` | Self-host DOCX worker and JSZip assets. | | `docx.workerTimeout` | Worker startup timeout. The default is 5000ms so unsupported paths, MIME, CSP, or WebView environments fall back quickly. | | `docx.progressive` | Lets the renderer yield between batches to improve first content and scroll responsiveness on large documents. | | `docx.visualPagination` | Optional fixed-height, measured pagination. Continuous flow is the default; it preserves author-inserted page breaks and section boundaries, but does not automatically split long tables or paragraphs. | | `docx.reviewMode` | Text revisions in DOC and DOCX: `all` (default) keeps insertions underlined and deletions struck through; `final` shows the revised text and `original` shows the text before those changes. Text revisions include tracked tabs, soft breaks, and paragraph marks; removing a paragraph mark joins content within the same text flow or table cell. This does not accept or reject revisions in the source file. | | `text.htmlView` | Initial HTML/HTM view: `preview` (default) or `source`. The page/source buttons switch views. Preview preserves inline styles and embedded images in an isolated sandbox; scripts, forms, external navigation, and external resources are blocked. This is a static document preview, not a website runtime. | | `text.encoding` | Decoder for text, code, Markdown, HTML, XML, patch files, and LRC lyrics: `auto` (default), `utf-8`, `utf-16le`, `utf-16be`, `gbk`, `gb18030`, `iso-8859-1`, `iso-8859-2`, `iso-8859-15`, `windows-1250`, `windows-1251`, or `windows-1252`. Auto mode checks a BOM, UTF-16 byte structure, and strict UTF-8 before using `text.fallbackEncoding`. Use an explicit encoding for known legacy sources whose bytes are also valid UTF-8. Browsers decode `iso-8859-1` with the Windows-1252 table, as the WHATWG Encoding Standard requires. | | `text.fallbackEncoding` | Encoding used after auto detection fails: `utf-8`, `gbk`, `gb18030`, or any single-byte label above. Defaults to `gb18030`, preserving existing GBK support. Set `windows-1252` for Western European legacy files or `windows-1251` for Cyrillic ones. Ignored when `text.encoding` is explicit. Download retains the original bytes. | | `spreadsheet.worker` | Spreadsheet worker mode. The default `auto` keeps small files on the main-thread compatibility path and automatically tries the worker once file size reaches `spreadsheet.workerAutoThreshold`; explicit `true` / `false` values still take precedence. | | `spreadsheet.workerAutoThreshold` / `spreadsheet.workerUrl` | Large-file threshold for `worker: 'auto'` in bytes, default 1MB, plus the self-hosted Excel/XLSX worker URL. | | `spreadsheet.textEncoding` | CSV / TSV encoding override: `auto` (default), `utf-8`, `gbk`, or `gb18030`. Auto mode validates UTF-8 first and otherwise uses the browser GB18030 decoder. | | `spreadsheet.resizableColumns` | Allows users to drag spreadsheet header edges to inspect truncated text. | | `spreadsheet.fillViewport` | Excel only; default `false`. Adds empty alphabetic column headers, row numbers and virtual grid cells at the worksheet's default sizes to fill small or empty previews. Recalculates on resize/zoom without changing workbook data, used range, exports, search or content counts. Other spreadsheet formats ignore it. Example: `options: { spreadsheet: { fillViewport: true } }`. | | `presentation.workerUrl` / `presentation.workerType` | Self-host the `@file-viewer/pptx` worker or override its Worker type for strict CSP, legacy WebViews, or custom static asset routing. | | `presentation.pptModuleUrl` / `presentation.pptWorkerUrl` / `presentation.pptWasmUrl` / `presentation.pptFontUrl` | Advanced overrides for the packaged PowerPoint 97–2003 `.ppt` 0.3.4 ESM, Worker, WASM, and CJK font asset routes. Demo, Vite/full, copy-assets, and CDN/IIFE builds work without them. | | `presentation.pptWorker` / `presentation.pptCache` | Select `auto` / required / disabled binary-PPT Worker rendering and configure or disable its bounded IndexedDB frame cache. | | `pdf.streaming` / `pdf.rangeChunkSize` | Controls URL-based progressive PDF loading and PDF.js range chunk size. | | `pdf.toolbar` | Shows or hides the PDF renderer's own page / zoom / rotation toolbar. Useful for comparison layouts. | | `pdf.navigation` / `pdf.defaultNavigationVisible` | Enables the left page / outline navigation pane and initial visibility. | | `pdf.bbox` | Highlights and focuses one or more PDF regions. Supports normalized ratios, percentages, native PDF points, and OCR pixels with explicit source dimensions. | | `pdf.workerUrl`, `pdf.cMapUrl`, `pdf.wasmUrl`, `pdf.standardFontDataUrl` | Self-host PDF.js worker, CMap, WASM, and standard font assets. The default worker path is probed first and falls back to the packaged PDF.js handler when unavailable. | | `cad.wasmPath`, `cad.workerUrl`, `cad.dwfWasmUrl` | Self-host LibreDWG and DWF / DWFx / XPS assets. | | `cad.renderer` | `auto`, `webgl`, or `canvas2d`; default is `auto`. | | `cad.workerTimeoutMs` | DWG parsing timeout; `0` disables the limit. | | `typst.compilerWasmUrl`, `typst.rendererWasmUrl`, `typst.fontAssetsUrl` | Self-host Typst compiler / renderer WASM and bundled fonts. | | `drawing.viewerScriptUrl` | Same-origin self-hosted diagrams.net / draw\.io viewer script used only when `drawing.preferOfficial` is explicitly enabled. The optional runtime is isolated in a no-same-origin iframe with restrictive CSP and falls back to safe SVG output when it cannot load. | | `data.sqlWasmUrl` | Self-host SQLite WASM for `.sqlite` previews. | | `binary.maxFileBytes` / `binary.maxParseMilliseconds` / `binary.maxStructureNodes` / `binary.maxStructureDepth` / `binary.maxStringBytes` | Bound the explicit binary-inspector Worker input, parse time, tree complexity, and decoded strings. Defaults are 16 MiB, 5 seconds, 512 nodes, 16 levels, and 4 KiB. | ## Operation Guard [#operation-guard] ```ts const options = { async beforeOperation(context) { if (context.operation === 'download') { return await checkPermission(context.source) } return true }, toolbar: { position: 'bottom-right', items: { 'zoom-reset': false }, permissions: { print: canPrint } } } ``` Built-in operation keys are `download`, `print`, `export-html`, `zoom-in`, `zoom-out`, and `zoom-reset`. `toolbar.items` only controls the built-in toolbar UI, so teams can replace selected buttons with their own native controls. `toolbar.permissions` is a hard gate: a `false` value blocks both the built-in toolbar and direct controller / ref API calls before custom `beforeOperation` hooks run. Returning `false` from any guard cancels the operation. Print delivery notes: * `printRenderedHtml()` prints the full rendered document and keeps the current watermark when `options.watermark` is enabled. * `printWithMask()` opens the page-aware mask and stamp designer. It can draw black cover regions or upload a local PNG, JPEG, WebP, GIF, or SVG stamp, then move, resize, remove, and print it under the watermark. Uploaded files stay in the browser as data URLs. The designer is loaded asynchronously inside core, so installing a component package is enough—no extra subpath alias is required. * Custom toolbars can call either API directly; `printRenderedHtml({ mask })` also accepts precomputed `regions` and `stamps`. Stamp geometry uses percent `left`, `top`, `width`, and `height`, with optional `pageIndex`, `opacity`, `rotate`, and `alt` fields. * Export / print HTML inlines ephemeral `blob:` image URLs as portable `data:` URLs, so DOCX figures remain visible after download or in the print window. * CAD export captures the current camera view / current native DWF page, including WebGL vectors and text overlays. Source mode uses a dark background and adaptive contrast; monochrome uses black lines on white paper. Explicit background options take priority. The native PNG/JPEG downloads retain text/image watermarks, use the owning viewer's download hooks, and require both download and HTML-export permissions. `cad.showImageExport: false` hides those buttons. HTML embeds the PNG and Print supports Save as PDF. Use Fit before exporting a whole drawing; this is not a multi-sheet vector PDF converter. Component teardown follows the host framework lifecycle. Vue 3 / Vue 2 component unmount, React unmount, Web Component `disconnectedCallback`, Svelte action `destroy`, and jQuery plugin `destroy` all enter the same controller teardown path: active loading is cancelled, the renderer session is destroyed, rendered DOM is cleared, zoom/search/view-state observers are stopped, and `unload-start` / `unload-complete` fire with `reason: "component-unmount"`. In Element Plus `el-dialog destroy-on-close`, route switches, tab closing, or `v-if` removal, host code does not need to clear the viewer container manually. When the host only hides the viewer, such as `v-show`, a dialog without `destroy-on-close`, or KeepAlive, the active document remains mounted. Use this when preserving reading position is desired. If the product needs explicit teardown while keeping the surrounding component alive, call `destroy()` on the component ref or controller, then recreate the viewer before previewing again. ## Lifecycle Hooks [#lifecycle-hooks] ```ts const options = { hooks: { onLoadStart(context) { console.log('loading', context.type, context.filename) }, onLoadComplete(context) { console.log('loaded', context.rendererId, context.duration) }, onUnloadStart(context) { console.log('unloading', context.reason) }, onUnloadComplete(context) { console.log('unloaded', context.filename) } } } ``` ## Toolbar Customization [#toolbar-customization] Framework packages expose the same operation model with ecosystem-native customization: | Stack | Customization style | | ---------- | ---------------------------------------------------------------------------------------- | | Vanilla JS | `options.toolbar`, Custom Element properties, `mountViewer(...)`, and controller methods | | Vue | props, emits, and component refs | | React | props, callback props, and `ref` handle APIs | | Svelte | props, events, actions, and bindable references | | jQuery | plugin options, events, and returned instance methods | Toolbar buttons should call viewer operations rather than wrapping rendered content with outer CSS transforms. This keeps spreadsheet coordinates, PDF text layers, CAD canvases, and mobile gestures aligned. The initial zoom label is not assumed to be `100%`. Renderers report the actual scale after first-screen fit, image natural-size loading, PDF / Word layout, container resize, or any internal reflow. Built-in toolbars and `getOperationAvailability()` use the same state to keep `zoomIn`, `zoomOut`, and `zoomReset` accurate. Custom toolbars should sync from `zoom-change` or `getZoomState()` instead of caching their own default percentage. The percentage baseline follows the renderer's coordinate system. For Word/DOCX, `100%` is the document page's natural CSS size, so `120%` means the layout width multiplied by `1.2`, not the current fit-width result enlarged by another 20%; a mobile fit can therefore start below `100%`. CAD has no useful cross-file CSS physical size, so its `100%` is the most recent fitted camera view and later buttons, wheel input, or pinch gestures report a ratio relative to that view. Do not convert percentages across formats into a paper-scale measurement. ## View State Sync [#view-state-sync] `initialViewState`, `view-state-change`, `getViewState()`, and `applyViewState()` are designed for projection systems, remote-control displays, side-by-side comparison, and reading-position restore. Every standard renderer path registers a view-state provider. Renderers without a dedicated provider use the generic DOM provider, which records the renderer id, current zoom, and scroll ratios. PDF adds page, page count, rotation, and navigation state. XMind adds sheet index, panX, panY, and zoom. Geo adds map center, zoom, bearing, and pitch. 3D adds camera position, target, and display options. CAD reports the view snapshot exposed by the underlying CAD viewer. ```ts let lastState = null const options = { initialViewState: { page: 3, scale: 1.25, scroll: { topRatio: 0.18 } } } function onEvent(event) { if (event.type === 'view-state-change') { lastState = event.payload.state sendToDisplay(event.payload) } } await displayViewer.applyViewState(lastState, { source: 'api', action: 'restore' }) ``` A custom PDF toolbar can read the page snapshot and apply a partial state for previous, next, or page-input navigation: ```ts const state = viewerRef.value?.getViewState() const page = Number(pageInput.value) await viewerRef.value?.applyViewState( { page }, { source: 'api', action: 'page-change' } ) await viewerRef.value?.applyViewState( { page: Math.min((state?.page || 1) + 1, state?.pageCount || 1) }, { source: 'api', action: 'page-step' } ) ``` For synchronization, send the full `state` snapshot instead of replaying individual button clicks. PDF page changes, zooming, scrolling, XMind panning, Geo map movement, and 3D camera updates all use the same event shape; the display side only needs to call `applyViewState()`. High-frequency projection updates may be coalesced to one snapshot per animation frame, but do not use a trailing-only debounce that waits until scrolling stops. Use `pdf.bbox` to highlight and focus a region on first load, or replace/clear it dynamically through `applyViewState()`. Pages are one-based. OCR pixel coordinates use `pixel` plus the source image dimensions. Native PDF coordinates use `pdf-point` and default to a bottom-left origin. `ratio` and `percent` default to a top-left origin. A single box or an array is accepted, and highlights stay attached through zoom and rotation. ```ts const options = { pdf: { bbox: { page: 3, x: 120, y: 240, width: 360, height: 64, unit: 'pixel', sourceWidth: 1440, sourceHeight: 2036, label: 'Contract amount' } } } await viewer.applyViewState({ page: 5, extra: { bbox: { page: 5, x: 72, y: 640, width: 220, height: 36, unit: 'pdf-point' } } }, { source: 'api', action: 'bbox-focus' }) await viewer.applyViewState( { extra: { bbox: null } }, { source: 'api', action: 'bbox-clear' } ) ``` PDF default assets are probed from the site root (`/vendor/pdf/...`) so Vue Router, React Router, and other deep routes do not accidentally request `vendor/pdf/pdf.worker.mjs` from the current page path. When the static worker is missing or an app server falls back to HTML, the PDF renderer lazy-loads the packaged PDF.js worker handler as a compatibility fallback. Use absolute `pdf.workerUrl`, `pdf.cMapUrl`, `pdf.wasmUrl`, and `pdf.standardFontDataUrl` when deploying under a sub-path, a dedicated static asset domain, or a strict CSP. PPTX uses the `@file-viewer/pptx` worker on demand; set `presentation.workerUrl` and, when necessary, `presentation.workerType` for custom worker routes. Binary `.ppt` uses `@file-viewer/ppt@0.3.4`; standard distributions keep its verified ESM/Worker/WASM/font files together under `vendor/ppt/`. Configure `presentation.pptModuleUrl`, `pptWorkerUrl`, `pptWasmUrl`, and `pptFontUrl` only for a custom layout. --- # Modular Profiles and Full Compatibility (/guide/v3-modular-profiles) ## Profiles are explicit install contracts [#profiles-are-explicit-install-contracts] | Profile | Contract | Use it when | | ------------- | ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | | `standard` | Common document, PDF/OFD, modern PPTX, spreadsheet, archive, email, text, image, and media capabilities with selective assets | A new application needs broad everyday coverage without specialist engines | | `lite` | Text, Markdown/code, image, audio, and video | Attachments are mostly lightweight web formats | | `office` | The established Office preset and its compatibility formats | An Office-focused integration relies on that exact preset | | `engineering` | The established engineering preset | The product needs CAD, 3D, EDA, Geo, or related engineering formats | | `all` | The published `@file-viewer/preset-all` compatibility matrix | A modular application already depends on `preset-all` | | `full` | The matching historical `@file-viewer/*-full` package plus later explicit opt-ins known by the CLI | Install size is acceptable and the product deliberately wants every catalog capability | | `custom` | Only the capabilities selected in project config | Dependency ownership must be exact | The profile controls package installation and renderer registration. Runtime loading remains format-driven: a selected heavy renderer is fetched only when a matching file is opened. ## Frozen standard baseline [#frozen-standard-baseline] `@file-viewer/preset-standard` includes these package-level groups: * Word, DOCX, DOC, RTF, and OpenDocument text; * PDF and OFD; * modern OpenXML PowerPoint through `@file-viewer/renderer-pptx`; * Excel, CSV/TSV, OpenDocument Spreadsheet, and DBF; * archives and email; * text, code, Markdown, images, audio, and video. Specialist capabilities such as iWork, DICOM, digital-signature containers, CAD, 3D, EDA, Geo, Typst, drawing, WordPerfect, Hangul, and legacy binary PPT stay explicit. This keeps additions to the global format catalog from silently growing every standard install. The PPT split is also an install boundary. Modern `.pptx` uses `@file-viewer/renderer-pptx`. Legacy `.ppt` uses `@file-viewer/renderer-ppt` and its separately licensed runtime. The compatibility aggregate `@file-viewer/renderer-presentation` continues to provide both for existing users. ## Existing Full packages do not change [#existing-full-packages-do-not-change] The eight published `@file-viewer/*-full` packages keep their existing: * `preset-all` capability matrix; * public API and default integration behavior; * runtime asset paths and copy-assets behavior; * formats that were part of the package when released. They will not be silently switched to `standard`. Installing one of those packages directly also does not promise that every specialist renderer introduced in a later release will become a new transitive dependency. That rule prevents an unchanged application from accumulating unbounded downloads as the catalog grows. The CLI's `--profile full` is an explicit convenience contract. It preserves the matching compatibility Full package, then adds the later opt-in capabilities in the installed CLI catalog. The CLI shows package weight and license information before it asks for confirmation. ```bash npx file-viewer-cli plan --framework vue3 --profile full npx file-viewer-cli create my-viewer --framework vue3 --profile full --yes ``` The current later opt-ins are DICOM and digital-signature containers. The DICOM renderer covers one local Part 10 file, including multi-frame navigation; it does not provide series assembly, PACS/DICOMweb, MPR, segmentation, diagnostic interpretation, or an embedded OHIF application. The signature renderer performs bounded local inspection of CMS/CAdES, timestamps, ASiC, evidence records, JWS, and public OpenPGP material. It keeps cryptographic results separate from trust, policy, qualified-signer identity, and legal validity; it accepts no private key and never follows remote key URLs automatically. ## Add specialist formats only when needed [#add-specialist-formats-only-when-needed] Select file extensions or capability ids on top of `standard`: ```bash npx file-viewer-cli create viewer \ --framework react \ --profile standard \ --formats dwg,typst \ --yes ``` Or evolve a configured project: ```bash npx file-viewer-cli config add dwg --write npx file-viewer-cli config add dicom --write npx file-viewer-cli config add p7m --write npx file-viewer-cli plan npx file-viewer-cli install --yes npx file-viewer-cli verify --json ``` The generated integration module imports only the fixed profile and selected additions. `plan` reports the exact packages, asset owners, heavy capabilities, and license notices. Use its current catalog output instead of copying historical package-size numbers into deployment policy. ## Capability contract [#capability-contract] Renderer packages can publish `file-viewer.capability.json` through `package.json#fileViewer.capabilityManifest`. The schema records: * owned formats and renderer ids; * public-asset renderer ids; * SPDX license and distribution policy; * `light`, `standard`, or `heavy` install weight; * preset/profile membership. The CLI catalog is generated from those declarations plus `ecosystem/format-catalog.json`. Repository gates reject format drift, unknown asset ids, a heavy capability entering `standard`, or a profile/package dependency mismatch. ## Recommended migration [#recommended-migration] 1. Leave existing Full and `preset-all` applications on their current packages unless there is a product reason to change them. 2. Use `standard` for new common-format applications and add specialist capabilities explicitly. 3. Run `file-viewer plan` before installation and commit `file-viewer.config.json` as the selection record. 4. Deploy only the selected runtime assets, or retain the complete compatibility copy-assets workflow where an existing Full installation requires it. 5. Run `file-viewer doctor` and `file-viewer verify` in CI so package, generated-module, receipt, and asset drift fails before deployment. See the [complete CLI guide](/guide/cli) for scaffold creation, existing-project detection, asset compatibility, private registries, and offline tgz preparation. --- # XML validation and transformation (/guide/xml-profiles) Available in 3.1.2 and later. Ordinary `.xml` files still use the text renderer. Install and explicitly enable profiles when your application needs XSD validation and an XSLT-generated document view. ## Setup [#setup] Install the optional engines and copy their assets from your installed packages: ```sh npm install @file-viewer/web @file-viewer/renderer-text xmllint-wasm@5.3.0 xslt-polyfill@1.0.29 npx --no-install file-viewer-xml-assets public/file-viewer/xml ``` Serve the copied runtime files and licenses from your own origin. The copier checks engine versions and writes a SHA-256 manifest; it never downloads packages. Standard text and Full imports do not load these engines. ```ts import { mountViewer } from '@file-viewer/web' import { textRenderer } from '@file-viewer/renderer-text' import { enableFileViewerXmlProfiles } from '@file-viewer/renderer-text/xml-profiles' const disableProfiles = enableFileViewerXmlProfiles() mountViewer(document.querySelector('#viewer'), { url: '/documents/invoice.xml', filename: 'invoice.xml', options: { renderers: [textRenderer], xml: { profilesUrl: '/profiles/profiles.json', runtime: { xsdWorkerUrl: '/file-viewer/xml/xmllint-browser.mjs', xsltModuleUrl: '/file-viewer/xml/xslt-wasm.js' }, onDiagnostic: diagnostic => console.info(diagnostic) } } }) // Call disableProfiles() when the application's registration is no longer needed. ``` The component has **View Source** and **View Rendered** buttons after a successful transformation. Toggling does not fetch or parse the original again. `xml.initialView: 'source'` keeps source visible initially. Diagnostic callbacks are optional and do not determine whether rendering succeeds. ## Profile manifest [#profile-manifest] ```json { "profiles": [{ "id": "invoice-v1", "match": { "rootNamespace": { "enabled": true, "root": "invoice", "namespace": "urn:example:invoice:v1" }, "xsd": { "enabled": true } }, "xsd": "./invoice.xsd", "xslt": "./invoice.xsl" }] } ``` Resource paths are relative to the manifest URL. Alternatively, supply `xml.profiles` with `xml.baseUrl`; do not also set `profilesUrl`. Every enabled check must pass, and exactly one profile must match. Zero matches, multiple matches, malformed configuration, failed validation, unavailable assets or a transformation error all leave the original XML visible with diagnostics. XSD-only and root/namespace-only profiles are supported; at least one check must be enabled. XSD uses libxml2 through `xmllint-wasm`; XSLT 1.0 uses libxslt through `xslt-polyfill` in a Worker. It does not depend on the browser's native `XSLTProcessor`. Use HTML output in the stylesheet. XSD imports/includes, XSLT imports/includes, `document()`, extension instructions, DTDs and external entities are rejected. Flatten schemas and stylesheets into reviewed, self-contained resources before deployment. ## Limits and isolation [#limits-and-isolation] Resources must be same-origin HTTP(S), without redirects. Runtime URLs are application configuration, never taken from the XML document. The output is sanitized into a sandboxed iframe without scripts or same-origin access; it cannot execute application code or load external resources. Defaults and hard ceilings are 4 MiB XML, 2 MiB per schema/stylesheet, 8 MiB output, 32 profiles and 16 MiB total fetched resources. `xml.limits` can lower these limits. `timeoutMs` defaults to 15 seconds and is capped at 60 seconds. Workers are terminated on timeout, cancellation and unmount. Each WASM engine has a 64 MiB linear-memory ceiling. Larger or unsupported documents fall back to source; no validation result is fabricated. CSP must allow same-origin assets, blob Workers and WASM compilation. Keep the runtime JavaScript, WASM and license files together when deploying under a subpath, and update the two explicit URLs accordingly. The Demo includes a valid invoice and an invalid invoice to exercise both the rendered view and fallback. --- # File Viewer Documentation (/) File Viewer keeps private documents in the browser and avoids a server-side conversion pipeline. Start with a native component, add only the renderer capabilities you need, and publish every Worker, WASM, font, and vendor asset from your own origin. ## Start with the right path [#start-with-the-right-path] | Goal | Recommended guide | | ----------------------------------------- | ----------------------------------------------------- | | Run the shortest complete example | [Quickstart](/guide/quickstart) | | Integrate without a framework | [Vanilla JS and Web Component](/guide/quickstart-web) | | Choose standard, preset, or Full packages | [Ecosystem packages](/guide/ecosystem) | | Verify exact file coverage | [Supported formats](/guide/formats) | | Keep every runtime asset offline | [Distribution and self-hosting](/guide/distribution) | ## What the documentation covers [#what-the-documentation-covers] * Browser-native integration for Vanilla JS, Web Component, Vue, React, Svelte, and jQuery. * Standard packages, modular renderers, product-shaped presets, and complete Full packages. * PDF, Office, CAD, archives, email, media, drawing, code, 3D, and engineering formats. * Shadow DOM style isolation, theme tokens, toolbar customization, print, export, and search. * Docker, CDN/IIFE, private deployment, offline assets, and release verification. ## Verify before you ship [#verify-before-you-ship] The documentation is generated as semantic static HTML. Every canonical page has its own title, description, Open Graph and X metadata, structured data, raw Markdown endpoint, and English/Chinese alternate. Search runs locally in the browser; the published site does not require a documentation server. --- # 更新日志 (/zh/changelog) 这份日志记录的是当前仓库主线中,对外最值得说明的能力演进。 ## `v3.0.3` Word 修订、浏览器集成与移动端 PDF 修复 - 2026-09-09 [#v303-word-修订浏览器集成与移动端-pdf-修复---2026-09-09] * MapLibre 6.4.1 修复地图署名 HTML 连续危险属性的清洗绕过;离线 Worker 内置,地图销毁重建后仍能加载。同步更新 js-yaml、sharp 和 Vitest 安全版本,以实际所需 polyfill 替代未使用的 Browserify 工具链。 * 标准预览固定使用 JSZip 3.10.2,修复跨 JavaScript 上下文的二进制类型识别,并保持构建与冷安装版本一致。 * core 与各渲染器统一固定 DOMPurify 3.4.15,纳入 XML 消毒安全加固并避免冷安装重复引入多个版本,体积预算不变。 * Demo 顶部按钮悬停不再改变文档顶部留白或 CAD 导出尺寸。 * 二进制 DOC 保留插入/删除修订、段落和软换行标记;Word 可直接切换全部修订、最终稿和原稿,无需重选文件。修正 DOC 行距单位和字体槽位,按提供的销售合同验证正文和表格,不凭空添加修订线。 * 表格列宽拖拽后随缩放变化并按 sheet 恢复;不可见区域搜索覆盖真实 XLS、远列和合并单元格。CFB 只跳过未使用的损坏 MiniFAT 链,必需工作簿数据仍严格校验。 * 修复 iPhone Safari PDF 翻页及搜索键盘收起后的导航恢复;取消 PDF 初始化不再产生未处理的 Worker 终止异常。 * 修正 Vue CLI/Webpack、Angular 和嵌套 Vite 的浏览器入口及 PPTX Worker 资产定位,保留显式路径优先级。新增 RequireJS AMD 入口,不修改宿主 `define`,懒加载资源仍由本地提供。 * HTML 提供静态预览和原始源码切换,不执行脚本或外部请求。OFD 正确处理声明的资源路径和命名空间,必需页面错误不再挂起。CAD 修复 DXF LINE、DWF/DWFx 对比度,PNG/JPEG 当前视图下载遵守权限、钩子和水印。 * PDF 补丁携带可验证的来源哈希;CHM、Adobe 和 Illustrator 安全修复同步至分发 Worker。独立组件源码构建补齐输入,发布按依赖层批量推进,并按完整性校验安全续跑。 87 个主线包对齐 `3.0.3`,`msdoc-viewer` 升至 `0.2.6`。上游引擎为 DOCX `0.3.31`、styled-exceljs `0.21.6`、CAD `0.8.2` 和 DWF `0.6.7`。Vue 2.6/2.7 和既有 Full 能力不变,pako 3 继续暂缓。本 patch 同时包含 HTML 视图、AMD 入口和 CAD 图片下载等新增能力。 \#227 私有 XLS、#236 删除修订截图对应的文件及历史 #57 OFD 仍缺少原件;构造样本和已提供合同不能替代对应原件的验收。 ## `v3.0.2` 修正版:表格搜索、DOCX 形状与 CAD 单色输出 — 2026-09-06 [#v302-修正版表格搜索docx-形状与-cad-单色输出--2026-09-06] 本版取代 3.0.1。由于 npm 已有下游依赖,已发布的 3.0.1 不能被完整撤回;3.0.2 发布后会将仍可变更的 3.0.1 包标记为 deprecated。 ### 问题修复与回归 [#问题修复与回归] * 修复 #247:表格搜索不再受当前虚拟渲染窗口限制,会搜索已解析工作簿中的真实单元格,加载目标窗口并跳转到匹配位置;真实 `apps/viewer-demo/public/example/excel.xls` 已通过浏览器回归。 * 通过升级 `@file-viewer/docx` 到 `0.3.29` 修复 #250 的页面相对定位浮动 shape 问题;报告者的 `test.docx` 已在本地浏览器验证。 * 完成 #213/#245:CAD 单色策略从 DWF、CAD renderer 延续到 HTML/Print 输出,不修改原始数据;真实 DWF 回归通过。 * 重新执行 #242 的 Vite/PDF 中文字体资产边界、#232 的 `postal-mime@3.0.0` EML 正确性以及 Vue 2.6 CLI 3 Office 样例,Vue 2 仍在发布门禁内。 ### 可采纳依赖 [#可采纳依赖] * 采用安全的 Dependabot 子集:`pako@2.2.0`、`proj4@2.22.0`、`vite-plugin-dts@5.1.0`、`cnfast@0.2.0` 和 `prettier@3.9.6`。 * pako 3 继续暂缓,因为 DICOM `Inflate` 的错误/消息语义由 `packages/renderers/dicom/src/inspect.ts` 使用;Next 16.3.4 因引入 `sharp-libvips` 未通过 LGPL 许可证门禁。 ### 发布组成 [#发布组成] 同一提交冻结 88 个 npm 目标:87 个主线包为 `3.0.2`,历史 `msdoc-viewer` 别名保持 `0.2.5`;外部引擎为 `@file-viewer/docx@0.3.29` 和 `styled-exceljs@0.21.4`。 ## `v3.0.1` 宿主框架 peer 依赖、PDF 中文兜底字体与 EML 头部修正 — 2026-09-03 [#v301-宿主框架-peer-依赖pdf-中文兜底字体与-eml-头部修正--2026-09-03] ### 可读文本预览 [#可读文本预览] * 新增可选的可读文本预览(#235):普通与有界虚拟文本按逻辑行换行;结构化文本按格式懒加载 Prettier parser,以徽标和切换按钮区分格式化显示副本与原始源码。格式化阈值独立于大文本渲染,下载始终保留原始字节。 ### CLI 可靠性与交互 [#cli-可靠性与交互] * 新建项目的交互式格式选择改为预先列出 renderer/格式族并显示勾选状态;当前 profile 已包含的能力保持启用,额外能力支持编号、范围、全选和清空,不再要求手写扩展名。 * Vite 8 脚手架声明并在 `dev`/`build` 前校验 Node `^20.19.0 || >=22.12.0`,旧运行时会获得明确迁移提示;Web Component 事件从元素所属 document realm 创建,并为缺失全局 `CustomEvent` 的 DOM 环境保留兼容回退。 ### 新增格式渲染器 [#新增格式渲染器] * 新增 `@file-viewer/renderer-chm`:CHM 帮助文档在浏览器内离线解析,Rust/WASM 解包配合沙箱阅读器还原目录、正文与图片,不上传任何文件内容。 * 新增 `@file-viewer/renderer-design`:Adobe 设计文件离线预览,覆盖 PSD/PSB 图层、Illustrator 原生 PGF 与 PDF 兼容表面、IDML/ICML/INX、INDD/XD、现代 XFL 动画与色板、画笔等资源文件;作为显式按需包交付,Worker、WASM 与字体全部可自托管。 ### PDF [#pdf] * 修复 #242 报告的 3.0 打包失败(Vite 8 + pnpm 11 + Node 22):`@file-viewer/vite-plugin` 从 2.4 起就把 PDF 资产列为必需,2.4 之所以能通过,是因为 `@fontsource-variable/noto-sans-sc` 当时是 `@file-viewer/renderer-pdf` 的运行时依赖;3.0.0 把该字体降级为 devDependency,安装后的应用解析不到任何字体来源,必需资产缺失直接中断 `vite build`,因此回退 2.4 看起来像修复。3.0.1 把字体来源上移到启用 PDF renderer 的 preset:`preset-office`、`preset-all` 直接声明字体包,`preset-standard` 由 `@file-viewer/assets-standard` 提供;`@file-viewer/renderer-pdf@3.0.1` 的发布包内不再携带任何字体副本(tarball 已核对),而在确实没有字体来源时该资产改为可选,构建输出警告而不是失败,PDF 继续依赖文档内嵌字体。该资产归属与可选性由 #242 门禁与 profile 门禁持续校验。 ### 邮件 [#邮件] * EML 解析基线升级到 postal-mime `3.0.0`(#232):未声明字符集的部件按邮件头编码正确回退,折叠的 RFC 5322 头部完整展开,重复头部按首个生效,`to`/`cc`/`bcc` 保持原始顺序。 ### 生态组件安装 [#生态组件安装] * `@file-viewer/vue3` 不再把宿主框架 `vue` 作为运行时依赖安装,改为 `peerDependencies: ">=3.3 <4"`,与 Vue 2.6/2.7、React、Svelte、jQuery 组件保持一致;构建期图标库同步移入 devDependencies,直接运行时依赖只剩 `@file-viewer/core`。这修复了应用锁定的 Vue 版本与组件自带版本不一致时安装出两份 Vue 实例、组件挂载抛 `Cannot read properties of null (reading 'refs')` 并留下空白页面的问题。 * 新增宿主运行时契约门禁:生态组件的可安装依赖只允许 File Viewer 自身包,宿主框架必须且只能声明为 peer,且三条 Vue 版本线互不重叠;冷安装校验在安装完成后立即比对宿主框架的解析路径,出现重复副本时直接失败并给出可读原因。 * `msdoc-viewer` 历史兼容别名升到 `0.2.5` 以跟随 3.0.1 的 `@file-viewer/doc`:该别名按解析到的 Word renderer 版本发布,同一冻结版本无法二次发布。本次发布冻结 88 个 npm 目标:87 个主线包为 `3.0.1`,`msdoc-viewer` 别名为 `0.2.5`。 ### 依赖安全 [#依赖安全] * XMind 解析路径不再解析 `@xmldom/xmldom` 0.9.10:该版本带有 6 项安全公告,且均可由预览不可信文件时的 `DOMParser.parseFromString` 触发;依赖覆盖将整张依赖图锁定到 0.9.12,开源边界校验会持续确认该覆盖确实生效(#246)。 ## `v3.0.0` 模块化 CLI、专业格式按需安装与安全门禁 — 2026-08-27 [#v300-模块化-cli专业格式按需安装与安全门禁--2026-08-27] * 新增 `@file-viewer/cli`、`file-viewer-cli` 和 `create-file-viewer`,既可创建新项目,也可在已有 `package.json` 工程中检测框架与构建工具后安装;支持选择框架版本、格式、preset、资源、npm/pnpm/Yarn/Bun、不含凭据的私有 registry 与完整性校验的离线 tgz。 * `standard` 成为常用格式的推荐方案,但不改变八个已发布 Full 包。`*-full` 继续交付原 `preset-all` 格式矩阵、API 和同版本离线资源;CLI 显式选择 `full` 时才在此基础上加入后续专业能力,并提前展示体积、运行时和许可边界。 * DICOM 和数字签名容器不进入未改动的 Full 依赖。可选 DICOM renderer 支持有界的本地单文件、单帧/多帧预览,覆盖未压缩、JPEG Lossless、JPEG-LS 和 JPEG 2000 Lossless;不声称诊断、PACS/DICOMweb 或多文件序列能力(#210)。 * 可选签名与证据容器 renderer 有界检查 CMS/CAdES、RFC 3161/5544、ASiC-S/E、RFC 4998、JWS 和公开 OpenPGP 材料。它使用许可宽松的 rPGP Worker/WASM,不包含 LGPL 源码,并分开报告解析、摘要/签名检查、信任和法律效力(#206)。 * 修复 #200 报告者提供的五页 PPTX 布局样例,覆盖 DrawingML 表格边界/内边距、SmartArt 水平文字、复杂形状和 PPTX Worker,并通过 Chromium、Firefox 与 WebKit。 * 还原 #211 报告样例的 Excel 表格主题、表头和交替行样式,列宽拖拽在切换 sheet 后继续保留;同时增加 #203 异常合并信息和稳定 Office 列宽回归。 * React、React Full、React Legacy 和 React Legacy Full 支持邮件附件嵌套预览,并覆盖恶意附件名、缓冲区替换、卸载、Worker 和 Object URL 清理(#212)。 * 重新执行 #178 的 Office 365/WPS 单元格内嵌图、浮动图、TIFF、Worker 传输、双击大图和可选列宽拖拽回归。 * DOC、RTF、PPTX、Markdown、Mermaid、Drawing、PlantUML 和 Typst 的文档内容到 HTML/DOM 边界统一加固;外链默认阻断,CSP 与 Trusted Types 在 Chromium、Firefox 和 WebKit 通过。 * 冻结 84 个 npm 目标:83 个主线包使用 `3.0.0`,历史兼容包 `msdoc-viewer` 使用 `0.2.4`;外部自研引擎固定为 `@file-viewer/docx@0.3.28` 和 `styled-exceljs@0.21.4`。 * 正式发布只提升冻结提交在构建、测试、安全门禁、冷安装、浏览器矩阵和 `npm publish --dry-run` 中通过的原始 tarball;发布阶段不重建、不临时增加稳定版本。 ## `v2.4.0` 统一版本与冻结候选发布 — 2026-08-25 [#v240-统一版本与冻结候选发布--2026-08-25] * 根版本、GitHub Release 与 56 个常规 npm 包统一为 `2.4.0`;历史兼容包 `msdoc-viewer` 使用独立的 `0.2.3` 版本。 * Spreadsheet 与 iWork 渲染链升级到 `styled-exceljs@0.21.3`,覆盖无原型工作表映射、有界 XML/标签处理,以及文档生成 HTML、CSS、链接、图片和属性的安全序列化。 * 重新验证 #178 的 Office 365/WPS 单元格内嵌图、浮动图、TIFF、Worker 传输、双击大图和可选列宽拖拽;版本统一没有移除 Excel 列宽调整能力。 * 稳定发布只提升已通过完整构建、冷安装与 npm dry-run 的原始 tarball。预演回执固定源提交、包集合、字节大小和 SHA-512,正式发布命令不再重新构建。 ## `v2.3.2` 多页 TIFF 与 Vite 8 分块兼容 — 2026-08-24 [#v232-多页-tiff-与-vite-8-分块兼容--2026-08-24] * TIFF 路径按需加载 MIT 许可的 UTIF.js,支持 CCITT Group 4、多页纵向展示、整组缩放/旋转/适宽、页码状态,以及双击或键盘大图查看(#208)。 * 对编码大小、页数、单页尺寸、单页像素和累计解码像素设置硬限制;逐页转换会释放 RGBA 和 Object URL,普通 PNG/JPEG/WEBP 路径不加载 TIFF 解码器。 * Vite 8 改用 Rolldown `codeSplitting.groups`,Vite 5—7 继续使用 Rollup `manualChunks`;用户分组、优先级、输出数组和 `codeSplitting:false` 保持不变(#209)。 * 使用 #178 原始 Office 365/WPS 内嵌图片工作簿再次验证主线程、Worker、TIFF drawing 与大图查看路径,Excel 列宽拖拽能力没有被移除。 * 实际发布版本为 `@file-viewer/renderer-image@2.3.1`、`@file-viewer/vite-plugin@2.3.3`、`@file-viewer/preset-lite@2.3.1`,以及统一的 All/Full/copy-assets 2.3.6 补丁线;本版继续包含 v2.3.1 的全部安全修复。 ## `v2.3.1` 旧版 DOC 渲染安全补丁 — 2026-08-24 [#v231-旧版-doc-渲染安全补丁--2026-08-24] * 旧版 DOC 直接 HTML API 会对文档提供的字体名和生成属性正确编码,避免文档内容突破样式或 HTML 属性边界。 * DOC 外部链接改为默认阻断;内部书签保持可用,显式允许时也只接受 HTTP(S)、邮件、电话和安全相对地址。 * 标准挂载路径在文档标记进入 DOM 前使用 DOMPurify 3.4.13 再次净化,renderer CSS 通过 `textContent` 注入。 * 净化器只进入 DOC 懒加载路径;压缩后为 10,923 字节,并由 15 KiB 发布门禁约束后续增长。 * 修复版本为 `@file-viewer/doc@2.3.1`、`msdoc-viewer@0.2.2`、`@file-viewer/renderer-word@2.3.2`,以及 Office/Full/copy-assets 的 2.3.4 补丁线。 ## `v2.3.0` Office/iWork 扩展与真实文件修复 — 2026-08-20 [#v230-officeiwork-扩展与真实文件修复--2026-08-20] * 将 Pages、Numbers、Keynote、WordPerfect、Hangul、DBF、FB2、XLA/XLAM 与 POT 纳入稳定格式矩阵;当前唯一目录包含 221 个扩展名和 32 条预览链路。 * 完整发布 #174、#178、#179、#195、#198、#201—#204 对应修复;#200 因缺少原始 PPTX 继续保留。 * 修复 Excel Office 365/WPS 单元格内嵌图片、工作簿绘图、文件原始列宽、Shadow DOM 列宽拖拽,并支持双击图片放大;用户后续提供的 TIFF drawing 会按需在浏览器内解码,主线程、Worker 与大图预览使用同一路径。 * DOCX 引擎升级到 `@file-viewer/docx@0.3.27`,修复复杂框架、分节、定位页面和锚定内容;Worker 缓存参数同步到实际运行时版本。 * 加固 PPTX Worker 输出、Markdown 渲染、压缩包文件名解码、包依赖与离线 Worker/WASM 交付。 * PPTX 按需构建不再携带仅供二进制 PPT 使用的 CJK 字体和原生 WASM;Vite 5–8 会按 `package.json#exports` 正确解析 `renderer-presentation/pptx` 子路径(#205)。 * 源码和 GitHub Release 版本为 v2.3.0;npm 不可覆盖的更正包按实际版本使用 `@file-viewer/renderer-spreadsheet@2.3.2`、`@file-viewer/renderer-iwork@2.3.1`、`@file-viewer/renderer-word@2.3.1`、`@file-viewer/renderer-presentation@2.3.1`、`@file-viewer/vite-plugin@2.3.2`,以及 Office/Full/copy-assets 的 2.3.3 补丁线。TIFF drawing 元数据由 `styled-exceljs@0.21.2` 提供。 ## `v2.2.9` PPTX 与 Markdown 渲染安全补丁 — 2026-08-17 [#v229-pptx-与-markdown-渲染安全补丁--2026-08-17] npm 包于 2026-08-13 发布;GitHub Release 于 2026-08-17 完成最终归档。 * PPTX Worker 产生的 HTML、SVG、内联样式与全局 CSS 在进入预览 DOM 前统一经过严格净化;外部媒体/矢量资源 URL、危险链接协议、事件属性、脚本、全局选择器和不安全 CSS 声明会被移除。 * PPTX XML 中的超链接 tooltip、形状属性、颜色与字体字段获得入口级校验;正常本地片段、base64 图片、blob 媒体和生成类规则保持可用。 * Markdown 的 Marked 输出改为先经 DOMPurify 再插入文档,新窗口链接自动使用 `noopener noreferrer`;DOMPurify 3.4.13 与 Mermaid 11.16.1 同步进入直接依赖。 * 自托管 Chromium 门禁同时覆盖恶意 Markdown、伪造 PPTX Worker 与真实恶意 PPTX Worker,验证普通/虚拟化两条渲染路径均不执行脚本、不污染全局样式且不发起攻击者控制的请求。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。 ## `v2.2.8` 大表格、OFD 首屏与二进制 PPT 观感修复 — 2026-08-11 [#v228-大表格ofd-首屏与二进制-ppt-观感修复--2026-08-11] * Spreadsheet 自动列宽只对有界行集取样,避免每次适配时全量遍历大工作表。76 MB、259,702 行真实 XLSX 在修复后完成解析、布局和浏览器渲染(GitHub #173)。#193 的原始样例为 38,732,752 字节、100,545 行 × 20 列,worksheet 与 sharedStrings 解压后合计约 108 MB;冷首屏 4.194 秒,末行虚拟滚动、100,545 / 100,545 行缓存和无控制台错误均完成验证。 * OFD 页面在初始布局完成前禁用 transform transition,第一帧稳定后再恢复缩放动画;减少动效偏好仍被完整尊重(GitHub #194)。 * `@file-viewer/ppt@0.3.3` 保留开源二进制 PPT 强制水印,但从重复斜向覆盖改为单个右下角标记,在批准的空白帧 fixture 中覆盖像素从 9,145 减少到 644。水印仍由 native 最终帧合成且无关闭通道。 * PPT 水印的尺寸按 1x/2x/3x 设备像素比整数增长,避免 Retina 与其他高分屏上的半像素边缘;三种 DPR 均通过真实浏览器渲染和像素区域证明。 * PDF 缩放锚点(GitHub #191)和 HTML-in-WordDocument 旧版 DOC 容错(GitHub #192)随本版完成 GitHub Release、组件仓、Demo、文档、官网、Docker 与 npm 的统一分发。 * 官网可交互预览的 pointer ownership、悬停切换与移动端入口完成回归;发布工具对 npm 短暂超时、未确定 registry 状态和中断后续传改为显式保护。 * 能力矩阵保持 54 个 npm 目标、208 个扩展名和 25 条预览链路。 ## `v2.2.7` PDF 缩放定位与旧版 Word 容错补丁 — 2026-08-11 [#v227-pdf-缩放定位与旧版-word-容错补丁--2026-08-11] * PDF 工具栏的放大、缩小和 API 缩放会先记录当前页与页内可视比例,再在 PDF.js 完成重新布局后恢复同一锚点;连续点击也不会短暂切换活动页(GitHub #191)。 * 部分扩展名为 `.doc` 的文件实际是 CFB 容器,`WordDocument` 流中保存 GB18030/UTF-8 HTML 且没有 `0Table`/`1Table`。解析器现在会在 FIB 之前识别这种明确格式,过滤脚本等不安全内容并转换为正常 AST,不再报 `Missing table stream`(GitHub #192)。 * `flyfish-dev/docjs` 所属仓库同步当前 legacy DOC 引擎,并独立通过表格、WPS、OfficeArt 图片、文本框 story 和 HTML-in-WordDocument 样例回归。 * 官网的文件预览 Hero 增加可交互卡片、悬停焦点和主题切换,同时收紧桌面与移动端的信息层级。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。 ## `v2.2.6` 大文件、分页导航与 Office 交互稳定性补丁 — 2026-08-10 [#v226-大文件分页导航与-office-交互稳定性补丁--2026-08-10] * Spreadsheet 会在解析阶段按真实单元格收紧异常 worksheet dimensions,避免格式化到整张工作表的文件造成巨量空行/列;图表发现改为读取 worksheet relationship,不再重复把大型 worksheet XML 解压为字符串(GitHub #173/#175)。 * Vue 3 与其他窄宿主首次打开 Spreadsheet 时按实际可视宽度计算 fit,桌面宽容器仍保持 100% 初始比例(GitHub #172)。 * OFD renderer 新增上一页、下一页、当前页/总页数、手动滚动同步、首尾禁用状态与键盘导航;resize 后保留活动页,打印时隐藏导航工具栏(GitHub #177)。 * Word renderer 会在正确的 DOCX renderer 边界拦截内部关系和外部 URL 的默认导航,同时保留链接文字;旧版 DOC 的文本框 story 也会从底层结构恢复,不再只显示占位字形(GitHub #171/#183)。 * PDF 在目录跳转、翻页、旋转和缩放状态回放后保留当前页与可视锚点,页码和页面不再突然向上跳动(GitHub #184)。 * `@file-viewer/pptx` 修复 connector 起终点、翻转和零尺寸 viewport 的几何计算;File Viewer 仅同步正式引擎产物,并通过专用几何 harness 与完整浏览器回归(GitHub #176)。 * 官网重新整理导航、支持矩阵、商业版和移动端入口,补齐 canonical redirect、IndexNow 和机器可读引用元数据;Crawler URL 仍不会进入离线运行时资产错误扫描。 * 发布前后回归覆盖冷安装、全 workspace 类型检查、根测试、全量构建、离线与 renderer 资产、28 格式矩阵、PDF/DOCX/XLSX/PPTX Demo,以及八类标准组件浏览器入口。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。 ## `v2.2.5` 文档审阅、打印与 Office 图形渲染补丁 — 2026-08-01 [#v225-文档审阅打印与-office-图形渲染补丁--2026-08-01] * 文档比对页使用成熟的 `jsdiff` 对两侧提取文字逐行对齐,并在替换行内标记具体字符;提供新增、删除、修改、未变化计数、上下差异导航和“只看差异”。DOCX、Markdown、代码和纯文本是稳定路径;PDF 仅在文本层覆盖完整页面时展示,扫描 PDF 暂不内置 OCR(GitHub #145)。 * 打印蒙版支持上传本地印章图片,并按实际文档页拖动、缩放、删除和导出到打印 HTML;已有矩形蒙版与多 renderer 页索引保持兼容(GitHub #157)。 * 文件加载前可以通过统一守卫拒绝或确认来源;PDF 搜索/定位可聚焦真实可见区域,并修复边界框、同步滚动和旋转状态回放(GitHub #151/#154)。 * Geo renderer 增加天地图矢量、影像与地形底图预设;默认不开启公网请求,业务仍需显式提供可用配置(GitHub #153)。 * DOCX 页面背景与浮动覆盖层恢复正确层级;PPTX 清理残留图表节点,并修复组合形状中的梯形、平行四边形等几何映射和层级关系。 * 图片预览新增旋转并优化 Lightbox 缩放/拖动;首页部署修复旧 HTML 缓存被当作 JavaScript 模块返回造成的严格 MIME 报错。 * Vue 2.6 + Vue CLI 3 / webpack 4 客户样例、Docker 发布上下文、组件构建和公开仓边界均完成完整回归。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。 ## `v2.2.4` DOCX/CAD 运行时与沉浸式预览稳定性补丁 — 2026-07-28 [#v224-docxcad-运行时与沉浸式预览稳定性补丁--2026-07-28] * Vue 2.6 + Vue CLI 3 / webpack 4 客户样例改为真实 `preset-office` 加图片、视频、CAD、3D 的显式补充装配;PDF.js legacy 模块会整体隔离内部 `modules`、`module_cache`、`exports`、`require` 四个 webpack runtime 标识,避免首次 PDF 初始化污染宿主导出、重选文件后从 `undefined` 读取 `createFileViewerTranslator`。DOCX ESM alias、同一本地 PDF 连续选择、图片和视频真实浏览器回归同步固化。 * Word 链路升级到 `@file-viewer/docx@0.3.26`。日文模板的东亚字体回退、行高和 VML 文本框不再导致字符重叠(GitHub #155);Apache POI 输出的兼容 OOXML `w:hMerge restart/continue` 会规范化为真实列跨度,异常孤立 continuation 仍保持可读(GitHub #160);多分节中文简历中的浮动形状、定位尺寸和页内内容流恢复原有关系,目录不再被挤压错位(GitHub #161)。主线程与离线 Worker 使用同一版本,并用 `0.3.26` 资源查询参数避免旧 Worker 缓存残留。 * CAD 链路使用 npm `latest` 的 `@flyfish-dev/cad-viewer@0.8.0`。底层引擎新增 BOM 提取与表格安全的 CSV/JSON 导出接口,收紧 DWG/DXF 元数据边界,并把 LibreDWG WASM 升级到 0.7.9;复杂线型 STYLE 引用为空时,合法图纸不再因解析异常而无法加载。 * Word 链路升级到 `@file-viewer/docx@0.3.23`。东亚语言和主题字体按文档语言脚本解析并保留可靠的系统字体回退,悬挂制表位、目录缩进和 HTML 样式属性的渲染更接近 Word;Worker 与主线程继续使用同一解析行为。 * Archive renderer 在压缩包内选中 Shapefile `.shp` 时,会按同目录和同 basename 收集 `.dbf`、`.shx`、`.prj`、`.cpg` sidecar,生成有界的临时 ZIP 后交给既有 Geo renderer;多数据集压缩包不会串用属性或投影文件,普通压缩包预览路径保持不变(GitHub #148/#149)。 * Word 链路升级到 `@file-viewer/docx@0.3.22`。缺失或部分缺失 `sectPr` / `pgSz` / `pgMar` 的 DOCX 在共享解析层获得 A4 页面和 1 英寸正文边距兜底,主线程与 Worker 行为一致;显式自定义尺寸、横向布局、零边距和附件保持不变(GitHub #150)。 * OFD 渐进渲染进入最终 ready 状态时不再重新隐藏已经可见的内容,消除大文件预览的二次闪烁;89 页样例会记录可见性 mutation 并确认不存在 ready 后回退(GitHub #163)。 * STEP/STP 重复预览时,Three.js Canvas backing buffer 会按当前 CSS 尺寸与设备像素比持续校正;即使外部流程把 backing buffer 降到 1×,下一渲染帧也会恢复清晰分辨率(GitHub #164)。 * Demo 首屏只按收起后的文件胶囊预留文档起始位置;开始滚动后文档可以自然进入胶囊后方,继续保持全视口沉浸滚动和透明滚动条。 * 日语界面完成核心消息、工具栏和样例入口覆盖;54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变。 ## `v2.2.3` 工具栏隔离与演示文稿运行时兼容补丁 — 2026-07-21 [#v223-工具栏隔离与演示文稿运行时兼容补丁--2026-07-21] * Web、Vue 3、Vue 2.7、Vue 2.6、React、React Legacy、Svelte 与 jQuery 共用 Core 浏览器控制器。标准组件默认在 Shadow DOM 中渲染,业务全局 CSS 不再覆盖工具栏;需要参与宿主样式系统时仍可显式设置 `styleIsolation: 'none'`。 * 修复 Shadow/Light 模式在同一宿主重挂时的边界残留,并保护业务自行创建的 ShadowRoot:File Viewer 只管理自己的挂载节点,销毁不会清空业务内容。 * Vue 3 的组件样式和 renderer 样式进入真实 ShadowRoot;Vue 2.6 的事件、状态回调、命令与视图状态 API 和现代组件保持一致。 * PPTX Worker 兼容 Angular 22 application builder 的 `.angular/cache`、Vite 依赖优化和 `baseHref` 路径。 * 二进制 PPT 升级到 `@file-viewer/ppt@0.3.2`。自包含 Worker 修复普通 Vite 生产构建中的相邻模块 404;强制 Worker 模式已在全新临时应用中渲染 25 页真实 PPT,并确认 Worker、WASM 与字体请求全部返回 200。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变;组件浏览器矩阵与主 Demo 的 136 个样例均完成真实渲染回归。 ## `v2.2.2` EPUB 安全依赖与 Docker 响应头补丁 — 2026-07-17 [#v222-epub-安全依赖与-docker-响应头补丁--2026-07-17] * EPUB renderer 与缩略图包改为按需加载随包交付的本地引擎;构建固定组合 `epubjs@0.3.93` 与 `@xmldom/xmldom@0.9.10`,npm 用户的生产依赖树不再安装旧 XML DOM 包。 * 每次构建都会生成引擎 SHA-256、版本 manifest 和完整第三方 NOTICE;发布门禁会对两个 tarball 做全新官方 registry 安装与 `npm audit --omit=dev`,并验证不存在裸 `epubjs` import 或外部运行时依赖。 * Nginx 中带独立 `Cache-Control` 的 location 显式保留 `X-Content-Type-Options: nosniff` 与 `Referrer-Policy`,避免 location 级 `add_header` 关闭 server 级继承;`.mjs` 保持 `application/javascript`。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路不变;2.2.1 的 PDF 下载、DOCX 锚点和自托管模块修复全部保留。 ## `v2.2.1` 上传下载、DOCX 锚点与自托管运行时补丁 — 2026-07-17 [#v221-上传下载docx-锚点与自托管运行时补丁--2026-07-17] * 修复上传 PDF 完成渲染后下载为 0 字节(GitHub #139)。PDF.js 转移并分离输入 `ArrayBuffer` 后,Core 会使用仍然完整的原始 `File`;流式 URL 和合法空文件保持原有行为。 * Word 链路升级到 `@file-viewer/docx@0.3.21`:WPS/WPG/图片不再重复应用根锚点偏移,嵌套组变换和组内图片正确组合,同段落内的页面/段落锚点也会在真实布局后同步(GitHub #133);缺失页眉或页脚 root 的可选结构在引擎层直接跳过(GitHub #130)。 * Docker/Nginx 为 `.mjs` 返回正确的 JavaScript MIME,`nosniff` 下 PDF.js Worker、PPT 和其他 ESM 资产可以正常动态导入。 * CAD 运行时资源构建支持跨文件系统 `EXDEV`,暂存、复制、交换、回滚和部分清理失败均有确定行为;Docker 上下文和依赖缓存同步优化。 * 54 个 npm 目标、208 个扩展名和 25 条预览链路保持不变;PDF 上传下载、OFD→PDF、PPT、PPTX、复杂锚定 DOCX 和自托管容器均完成真实浏览器回归。#133 附件页面不再溢出,关键区块相对参考 PDF 的横向误差小于 0.4 pt、纵向误差约 2–3 pt。 ## `v2.2.0` 产品化 Demo、路径兼容与集中缺陷修复 — 2026-07-17 [#v220-产品化-demo路径兼容与集中缺陷修复--2026-07-17] * 主 Demo 重新设计为产品化预览工作台:桌面端使用紧凑导航轨、文件来源浮层、顶部文档操作和底部缩放 dock;平板与移动端自动收起非核心操作,暗色模式继续保留独立白色文档纸张。 * 显式 `?url=` 文件入口在首帧前进入沉浸模式,隐藏 Demo 品牌、样例、历史与外层状态,只保留预览器工具栏;桌面与移动端均为满视口文档容器滚动,不产生页面级滚动条。 * `@flyfish-dev/cad-viewer` 升级至 `0.7.0`。DWG Worker、DWF WASM、LibreDWG JS/WASM 四个运行时文件全部作为必需资产发布;复制过程先暂存并校验,再原子交换,失败会回滚,同时保留业务自定义 SHX 文件。 * STEP/STP、IGES/IGS 和 BREP 已通过本地 OCCT Worker/WASM 直接生成 Three.js 网格;装配层级、面颜色、适配、统一缩放、暗色场景、主线程回退以及子路径离线资源都进入真实浏览器回归。IFC 和 3DM 仍只提供准确的能力提示。 * Core 新增统一运行时资源基址 API,Vite 插件把 Full、preset 和独立 renderer 的 `copyAssets.baseDir` 同步到运行时。Angular 深层路由、相对 Vite base、SSR、Windows 分隔符、空格、中文目录,以及路径中包含 `assets` / `static` / `js` 的部署均有确定性回归。 * CSV/TSV 文本解析优先识别 UTF-8 BOM 和严格 UTF-8,无效 UTF-8 自动使用 GB18030(兼容 GBK);`options.spreadsheet.textEncoding` 可显式指定编码,二进制 XLS/XLSX 不进入文本解码路径(GitHub #124)。 * `options.text.lineNumbers` 为普通代码/文本提供可配置行号;行号不会污染复制、全文搜索或屏幕阅读器输出,大文件虚拟滚动和移动端宽度保持稳定(GitHub #125)。 * Markdown 不再被普通文本的 512 KiB 默认阈值自动切成源码视图;默认始终保持 `marked` 排版阅读面,只有显式设置 `options.text.markdownVirtualizeAboveBytes` 才会在超限后进入有界源码模式(GitHub #136)。 * `options.text.toolbar` 默认保持历史元信息栏;显式传 `false` 可隐藏代码、文本和超大 Markdown 源码视图顶部的类型、索引状态与行数,不会误伤 Viewer 全局工具栏(GitHub #137)。 * PPTX 样式会注入真正承载内容的 ShadowRoot,默认 Worker URL 统一从运行时资源基址解析;Web Full IIFE 和 Angular 子路径不再请求站点根 `/worker/pptx.worker.js`(GitHub #127/#129)。 * PDF.js 的 `:root` 变量同时作用于当前 `.pdf-shell`,容器高度由本地 ResizeObserver 维护;全宽 flex grow + `overflow-auto` 宿主在初始 fit、缩小和 forced-colors 下保持居中(GitHub #128)。 * 宿主应用预载 PDF.js 3.x 时,File Viewer 不再让 PDF.js 5.4 复用不兼容的全局 fake-worker handler;本包只在自己的 PDFWorker 初始化期间临时接管 handler,随后完整恢复宿主 namespace(GitHub #134)。 * 静态 PDF Worker 会在实例化前校验官方版本标记;若部署目录残留的 Worker 与当前 PDF.js API 不一致,会自动切换到随包交付的同版本 handler,避免 `API version does not match the Worker version`(GitHub #138)。 * DOCX 渲染器识别缺失页眉/页脚 root 的特定异常,只对该可选结构禁用 headers/footers 并重试正文,其他异常仍按原路径抛出(GitHub #130)。 * Word renderer 会先按文件签名区分 OOXML ZIP 与 CFB:扩展名误写为 `.doc` 的有效 DOCX 不再进入二进制解析器,真实 `.doc` 路径保持不变(GitHub #131)。 * 非 Full 的 `preset-office` 资产复制补齐 `vendor/xlsx/sheet.worker.js`;Vite 子路径、npm/pnpm 冷安装、生产构建和来源版本都加入回归(GitHub #135)。 * PowerPoint 97–2003 二进制 `.ppt` 使用 `@file-viewer/ppt@0.3.1` 的 Worker / OffscreenCanvas / WASM、独立 CJK 字体与有界帧缓存,与 PPTX OOXML 解析链路严格分流,并纳入统一缩放、打印、HTML 导出和真实浏览器样例回归(GitHub #123)。Demo、Full、copy-assets、CDN/IIFE 以及 Vue 2.6 + Vue CLI 3 示例都交付经过校验的九文件 `vendor/ppt/` 运行时,标准布局无需手工配置 URL。File Viewer 自身代码仍为 Apache-2.0,PPT 运行时保留包内独立 LICENSE/NOTICE 与公开水印。 * TSV 纳入 Spreadsheet pipeline;格式矩阵更新为 208 个扩展名、25 条预览链路;离线扫描同时阻止 Demo GitHub API 请求和 Typst/Chevrotain 公网默认值进入分发资产。 ## `v2.1.30` Full 包完整资产开箱契约 [#v2130-full-包完整资产开箱契约] * 仅执行 `npm install` 只完成 renderer 代码安装,不会自动把 Worker、WASM、字体和 vendor 文件发布到业务站点;完成下述 Vite、非 Vite 或 `web-full/dist` 交付路径后,才属于完整格式支持。 * 八个 `*-full` 包统一内置 `preset-all` 和同一套运行时资源默认值,PDF、Office、CAD、Typst、Archive、Draw\.io、SQLite 等不再因框架不同而使用不同路径。 * 七个框架 full 包精确依赖同版本 `file-viewer-copy-assets` 并直接提供复制 CLI;`web-full` 的完整 `dist/` 自带全部资源,可原样部署。 * Vite 插件识别 full 包后会在开发和构建阶段自动发布完整资产到部署基址下的 `file-viewer/`;自定义或空 `copyAssets.baseDir` 会同步运行时 URL,非 full 项目保持旧布局。 * Vite 开发服务器会在根路径、子路径、自定义或禁用 `publicDir` 时统一提供资产与完整性清单;`options.pdf.assetBaseUrl` 继续作为 PDF 全量资源覆盖,单项 URL 仍可单独覆盖。 * Svelte 与 Svelte Full 的包根默认导出固定为组件,action/controller 改走明确子路径,避免 Svelte 5 把 action 当组件挂载。 * 修复 CRA/Webpack 常见 `static/js` 及多级 assets 目录被误判为资源根的问题,子路径部署不再把 Worker/WASM 请求到静态脚本目录内。 * 批量发布脚本按 54 个 npm 目标的内部依赖稳定拓扑排序,并在依赖环或重复目标时提前失败。 * 新增八个 full 包资源合约、Vite 子路径与自定义目录、npm/pnpm 冷安装、CLI 完整复制以及真实 PPTX Worker 浏览器回归。 ## `v2.1.29` 集中缺陷修复 [#v2129-集中缺陷修复] * 修复 Vue 2.6 + Vue CLI 3 / webpack 4 示例上传 DOCX 后报 `renderAsync is not a function`(生产压缩后表现为 `u is not a function`):webpack 4 默认选择 `@file-viewer/docx` 的 UMD `browser` 入口,该入口再次经过 Babel 转译后会丢失 CommonJS 导出。 * 旧构建链通过 alias 固定使用 `@file-viewer/docx/dist/docx-preview.mjs`,Word renderer 同时兼容传统 bundler 将 CommonJS API 放在 `default` 的模块形状。 * `pnpm verify:vue26-cli3-office-demo` 不再只验证内置 PDF;冷安装本地 tarball 后会真实上传 DOCX、等待文档页出现,并确认离线 DOCX Worker 被请求。`build`、`noApiBuild`、`nginx` 三种模式均纳入回归。 * 修复标准组件启用 `styleIsolation: 'shadow'` 后 Excel 单元格内容空白(GitHub #117):`e-virt-table` 默认写入 `document.head` 的完整样式无法穿透 ShadowRoot,导致承载单元格文字的 overlayer 失去绝对定位并被画布裁掉。 * Spreadsheet renderer 会识别当前 `e-virt-table` 版本实际注入的完整样式,将其复制到渲染 ShadowRoot,并把 vendor `:root` 变量收敛到 host / `.excel-wrapper`;新增 harness 会先在 npm `2.1.23` 复现空白布局,再验证本地 Vite 开发与生产构建的多 sheet、合并单元格、公式、样式和 overlayer 几何关系。 * 移除 OFD vendor 对 `Array.prototype.pipeline` 的可枚举污染(GitHub #111),避免先加载 OFD 后 PDF.js 把数组误判为非法请求参数;OFD→PDF、PDF→OFD、重复切换和取消均纳入浏览器回归。 * 打印掩膜新增可选的零基 `pageIndex` 并保持旧全局坐标兼容(GitHub #112);浏览模式允许滚轮/触摸翻页,绘制只武装当前页一次,PDF、DOCX、OFD、PPTX 的导出页均提供稳定页索引。 * 修复 Vite 开发入口 `/src/main.*` 被误当成运行时资产目录(GitHub #113):资源基址排除 `/src/`、`/@fs/`、`/@id/`、`/@vite/` 和 `/node_modules/`,根路径/子路径 dev 不再请求 `/src/vendor/pdf` 或触发 fake worker / CMap EOF。 * Archive Worker 与 WASM 统一使用当前文档的运行时资源基址(GitHub #114/#115),同时保留显式绝对 URL 的最高优先级;ZIP、RAR5、7z、加密 ZIP 与 worker 失败边界均使用独立 Vite dev/build harness 验证。 * Vite 插件复制 PDF.js 资产时优先从 PDF renderer 自己的依赖树解析,并校验 API/Worker 版本和来源(GitHub #118);消费项目根安装 `pdfjs-dist 6.x` 时不会再覆盖 renderer 固定的 `5.4.624` worker。 * PPTX renderer 的完成 Promise 现在等待 Worker、整体渲染及异步图表后处理全部结束(GitHub #119);致命错误只触发错误事件,单页错误继续作为警告,切换文件或取消期间的旧任务无法回写完成状态。 * PDF 初始化和 ResizeObserver 统一重放规范化 fit 请求(GitHub #120/#121),保留 `padding`、`maxScale` 与三种 resize 策略;“1:1”固定回到 100%,居中按导航栏后的实际可视区域计算。 * CAD 引擎升级到 `@flyfish-dev/cad-viewer@0.6.6`(GitHub #122),修复 DWG 多段线闭合、保存 UCS/PLAN 初始视图及虚线/点线渲染。 * Web Full、Viewer Demo 和 Component Demo 构建完成后自动净化上游 Chevrotain/Typst 公网默认值;离线扫描只精确豁免 canonical/OG/Twitter 的静态元数据属性,同行运行时 URL 仍会被拦截。 ## `v2.1.28` Office 兼容性与 Vite 8 修复 [#v2128-office-兼容性与-vite-8-修复] * 修复部分 Word/WPS `.doc` 文件仅在行结束标记携带表格属性时,单元格多段落被拆出表格、合并列宽错乱的问题;真实客户附件与合成表格回归均已验证。 * DOCX 引擎升级到 `@file-viewer/docx@0.3.20`,底部图表图例按实际文本宽度整体居中,同时保持右侧饼图图例行为不变。 * 修复 Vite 8 使用 spreadsheet renderer 时 `@xmldom/xmldom` 命名导出未预构建导致的浏览器启动错误,并加入独立 Vite 8 harness 回归。 * 加固离线资产、包体预算与 npm tarball 校验;全仓版本和 workspace 依赖推进到 `2.1.28`。 ## `v2.1.27` 关键 PR 修复与缩略图能力 [#v2127-关键-pr-修复与缩略图能力] * 发布浏览器缩略图生成 API,覆盖 PDF、DOCX、XLSX、EPUB、OFD、Typst、PPTX 等格式,并强化取消、销毁和压缩包资源安全。 * 新增 CBZ/CBR 漫画阅读器,支持自然顺序、按钮/键盘/滑动导航及旧渲染会话清理。 * 修复 DOC 表格外边框继承与 Demo 集成 UI,补齐桌面/移动端回归验证。 * 版本提升至 `2.1.27`,用于避免覆盖 registry 中已有的旧 `2.1.26` 产物。 ## `v2.1.26` 超大文本稳定浏览与主题切换 [#v2126-超大文本稳定浏览与主题切换] * 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.26`。 * 文本、代码和 Markdown 超过 512 KiB 后自动使用稀疏行索引与有界虚拟滚动,不再一次性解码、高亮并挂载完整文件;52 万行代码、超长单行、全文搜索和尾部跳转均纳入真实 Chromium 回归。 * 工具栏新增可配置的手动浅色/深色切换按钮,支持 `toolbar.theme` 和 `toolbar.order`,并在重新渲染后恢复阅读位置(GitHub #97)。 * 发布已包含 DOCX / XLSX 图表预览修复及对应样例回归(GitHub #96)。 * GitHub 默认 `README.md` 改为 English,中文入口迁移到 `README.zh-CN.md`;中英文页面分别只展示对应语言的 Demo GIF。 ## `v2.1.25` PDF 渲染器兼容性修复 [#v2125-pdf-渲染器兼容性修复] * 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.25`。 * 修复 UMI v4 项目启动报错 `Invalid regular expression flag`(GitHub #98):`@file-viewer/renderer-pdf` 改为固定使用 `pdfjs-dist@4.10.38`,不再依赖新版 PDF.js 才需要的 JBIG2/OpenJPEG/QCMS/QuickJS wasm 辅助模块,PDF wasm 资源清单调整为可选(`required: false`)。 * 修复生产环境部署到二级路径(如 nginx 反代 `/workspace/`)时 PDF worker 路径解析错误(GitHub #99):worker、cMap、标准字体等 PDF 资源统一按 `document.baseURI` 解析,移除单独的"仅站点根目录"回退逻辑,与其他渲染器的资源路径解析行为保持一致。 * 同步刷新 `pdf.worker.mjs` 等本地 vendor 资源与 CAD wasm 拷贝脚本。 ## `v2.1.24` OFD 签章、DOC/PPTX 修复与打印体验 [#v2124-ofd-签章docpptx-修复与打印体验] * 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.24`。 * 修复 OFD 预览不显示电子签章(GitHub #94):恢复 SES 签章外观解析,支持 PNG/JPEG 与嵌套 OFD 印章叠加。 * 修复 DOCX 导出/打印 HTML 图片空白(GitHub #90):`blob:` 图片自动内联为 `data:` URL。 * 打印链路默认携带水印;新增掩膜打印与移动端打印下拉向上展开。 * 修复 `.doc` 内嵌 OfficeArt 图片解析(GitHub #87)与工具栏缩放按钮位移(GitHub #88)。 * 修复 PPTX Origin OLE EMF 图表渲染与空白 run 保留;DOCX 暗黑模式与远程 URL 规范化。 ## 当前主线 OFD 电子签章预览 [#当前主线-ofd-电子签章预览] * 修复 OFD 预览不显示电子签章的问题(GitHub #94):恢复 SES `SignedValue` 签章外观解析,支持 PNG/JPEG 印章图片与嵌套 OFD 印章,并按 `StampAnnot` 边界叠加到对应页面。 * 预览路径只提取印章外观,不做国密/证书验签,单个签章失败不会阻断正文渲染;新增 `seal-png.ofd` / `seal-ofd.ofd` 回归与 `pnpm --filter @file-viewer/renderer-ofd verify:github-94`。 ## 当前主线 DOCX/导出 HTML 图片修复 [#当前主线-docx导出-html-图片修复] * 修复 DOCX 导出 HTML / 打印时图片空白的问题(GitHub #90):`@file-viewer/docx` 预览默认使用会话级 `blob:` URL,导出克隆后在新文档中失效。 * 在 core 导出/打印统一链路把 `blob:` 内联为可移植的 `data:` URL,并在 adapter 导出前等待图片就绪;同一修复覆盖打印窗口与 HTML 下载。 ## 当前主线打印水印与打印掩膜 [#当前主线打印水印与打印掩膜] * 打印链路默认附带当前水印样式(`print-color-adjust: exact`),避免浏览器打印时丢掉水印层(GitHub #92)。 * 工具栏打印改为紧凑下拉:点击「打印」后可选「直接打印」或「掩膜打印」;掩膜打印进入拖拽黑块设计流程,确认后再打印。 * 移动端底部操作面板与浮动工具栏的打印下拉改为向上展开,避免盖住底部快捷入口或被裁切。 * 掩膜设计器通过 core 内部动态 `import('./print-mask')` 异步加载,不打进主包;组件侧统一调用 `printWithMask()` / `printRenderedHtml({ mask })`,安装组件即可开箱使用,无需用户配置 `@file-viewer/core/print-mask` 子路径 alias。 * 打印 HTML 在内容之上、水印之下叠加黑色遮盖块。 ## 当前主线 `.doc` 内嵌图片解析修复 [#当前主线-doc-内嵌图片解析修复] * 按 MS-DOC `PICFAndOfficeArtData` / MS-ODRAW OfficeArt BLIP 规范解析内嵌图片,不再只靠魔数扫描;修复把 OfficeArt 内嵌 PNG/JPEG 误判为 `image/emf` 或 `application/octet-stream`,导致浏览器空白占位的问题(GitHub #87)。 * 新增 OfficeArt FBSE/BLIP 提取、DIB→BMP、压缩 EMF/WMF zlib 解压与 SVG 转换,以及 PICF 显示尺寸(`dxaGoal`/`dyaGoal`/`mx`/`my`)应用到 ``。 * 增加 `image-embedded.doc` 回归 fixture 与 `pnpm --filter @file-viewer/doc verify:github-87`,锁定 PNG/JPEG 内嵌图可解析、可渲染。 ## 当前主线工具栏缩放按钮位置修复 [#当前主线工具栏缩放按钮位置修复] * 修复默认工具栏从 100% 点击“放大”后,“1:1”还原按钮精确出现在“放大”按钮原位置,导致连续点击时第二次点击变成误触发“还原”而非继续放大的问题(GitHub #88):工具栏为右对齐布局,且两个图标按钮宽度相同,原实现把“1:1”插入在“放大”按钮之后,右对齐重排会让“放大”整体左移一个按钮宽度,新按钮正好顶替上“放大”刚才的像素位置。 * 调整为“1:1”按钮插入在“放大”按钮之前,让“放大”按钮始终保持工具栏最右侧的锚点位置,显示/隐藏“1:1”不再引起它的位移;新增 DOM 顺序回归测试和真实浏览器坐标验证,锁定该行为避免回归。 ## 当前主线 DOCX 暗黑模式适配 [#当前主线-docx-暗黑模式适配] * DOCX 渲染引擎升级到 `@file-viewer/docx@0.3.18`,同步刷新 `vendor/docx/docx.worker.js` 和缓存版本参数,确保本地 Demo、web viewer 与 compat viewer 使用同一版离线 Worker。 * `options.theme: 'dark'` 会自动启用 DOCX 暗黑渲染;`theme: 'light'` 保持浅色文档面;`theme: 'system'` 继续跟随浏览器 `prefers-color-scheme`。需要业务强制覆盖时可设置 `options.docx.darkMode: true / false`。 * 新增 DOCX 暗黑样式回归断言,覆盖 viewer 背景、DOCX 包裹层、文档页颜色和 `color-scheme`,避免暗色模式下出现白块、透明底或文字对比度异常。 ## `v2.1.20` 压缩包中文文件名与 full 资产路径修复 [#v2120-压缩包中文文件名与-full-资产路径修复] * 修复未声明 UTF-8 的 GBK/GB18030 ZIP 文件名乱码问题,兼容客户压缩包中中文文件名目录展示。 * 区分旧编码 ZIP 的兼容解码路径和真正的 libarchive Worker 失败,避免错误显示 “libarchive Worker 未能启动” 提示。 * Vue 3 / Vue 2.7 / Vue 2.6 full 包默认补齐 `/file-viewer/` 下的 Archive、PDF、Office、CAD、Typst 等离线资产 URL,并保留自定义 asset base URL 能力。 ## 当前主线官方 Demo iframe 交付包 [#当前主线官方-demo-iframe-交付包] * 新增 `iframe.html` 作为官方 Demo 的无外壳嵌入入口,支持 `?url=...` 直接预览业务文件,也支持 `?from=<父页面 origin>&name=<文件名>` 后由父页面 `postMessage(Blob)` 传入二进制文件;原主 Demo `index.html` 保留同一套协议,兼容既有集成。 * 新增 `file-viewer-v2-*-official-demo-iframe.tar.gz` release artifact,包内包含官方 Demo 构建产物、`iframe-example.html`、`README.iframe.md`、`iframe-manifest.json`、示例文件和离线 Worker/WASM/vendor 资源,客户可直接私有化部署。 * `release:standard:build`、`release:public`、`verify:demo-output`、`verify:demo-iframe-artifact` 和公开仓 `release-manifest.json` 校验全部纳入该产物,避免后续发布漏带官方 iframe Demo 包。 ## `v2.1.19` fit 适配与 Shadow DOM provider 补强 [#v2119-fit-适配与-shadow-dom-provider-补强] * 在 `v2.1.18` 离线资产发布基础上继续推进全仓版本到 `2.1.19`,确保最新源码、npm 包、公开仓、Release 资产和文档矩阵保持同一发布口径。 * core 的搜索、缩放和视图状态 provider 查找支持穿透 open ShadowRoot,Web Component / Shadow DOM 隔离模式下的工具栏、fit 和状态同步不再丢失内部 renderer provider。 * 图片、DOC 和 DOCX renderer 接入专属 fit provider,`fit:'width'`、`contain`、`scale-down` 等模式会基于真实图片尺寸或文档页面尺寸计算绝对缩放;图片未加载和文档暂不可测时会自动重试。 * 新增 ShadowRoot provider 回归测试,覆盖 provider 注册、查找和注销链路,避免样式隔离/组件封装后核心操作能力退化。 ## `v2.1.18` 离线资产、本地化发布与 DOCX 引擎更新 [#v2118-离线资产本地化发布与-docx-引擎更新] * 全仓版本、workspace 依赖和 release matrix 推进到 `2.1.18`;当前矩阵覆盖 52 个 npm 发布目标、16 个组件目标、27 条 smoke 渲染链、24 个 renderer pipeline、206 个扩展名和 432 个组件渲染目标。 * `libarchive.js` Worker / WASM 改为发布前自动从当前 lockfile 固定版本同步到 demo、component demo、web viewer、compat viewer 和 web-full 产物,`release:standard:preflight` 会强制校验这些本地资产,压缩包运行时不再依赖外部地址。 * 全仓离线运行时扫描扩展到 core、renderer、preset、组件、compat、demo public/dist 和 full IIFE async renderer 产物;默认禁止 CDN、官方域名 fallback 和第三方在线服务引用,Geo 默认公开底图作为明确例外保留。 * DOCX 渲染引擎升级到 `@file-viewer/docx@0.3.17`,同步刷新 `vendor/docx/docx.worker.js`、`jszip.min.js` 和缓存版本参数,确保 npm 包、demo、component demo、web viewer 和 web-full 都拿到同一版离线 Worker 资产。 * `sanitize:release-dist` 覆盖 public 与 dist 两类运行时资产,避免 `prepare-viewer` 或 full IIFE 构建后重新带入 Typst 字体 CDN、Chevrotain diagram CDN、Draw\.io 远端 fallback 等外链标记。 * Web Component / IIFE / web-full 默认走 Shadow DOM 样式隔离,框架组件可通过 `options.styleIsolation:'shadow'` opt-in;README、生态组件 README 和文档站同步说明 tokens、parts、hostile CSS 验证和旧 light DOM 兼容路径。 ## 当前主线 ViewerOptions.fit 统一适配能力 [#当前主线-vieweroptionsfit-统一适配能力] * `ViewerOptions` 新增 `fit`,支持 `auto`、`contain`、`cover`、`width`、`height`、`actual` 和 `scale-down`;未传 `fit` 时继续保持各 renderer 历史首屏行为,避免轻量接入被默认策略改变 * `fit` 对象形态支持 `{ mode, resize, padding, minScale, maxScale }`,其中 `resize` 默认 `until-interaction`:首屏和容器变化自动适配,用户手动缩放、平移或恢复视图后停止覆盖用户视角 * core 扩展 zoom / view-state provider 合约,新增 `fitToView()` controller/ref API 和 `fit-change` 事件;Web Component 支持 `` * PDF、图片、CAD、XMind、Geo 和 3D renderer 接入专属 fit provider,其他标准 renderer 通过通用 view-state provider 走内部 zoom provider 兜底;压缩包和邮件内嵌预览继承父级 `options.fit` * Demo 新增 fit 模式切换入口;显式 fit、resize、用户缩放暂停自动适配和 `fitToView()` 主动重算纳入通用浏览器 smoke / release matrix 体系,避免长期保留一次性 issue 验证入口 ## 当前主线工具栏定制能力 [#当前主线工具栏定制能力] * `toolbar.position` 新增 `top-center`,支持顶部操作栏水平居中;原有 `top` 继续保持顶部靠右,`auto` 和 `bottom-right` 行为不变,兼容已有接入 ## 当前主线视图状态同步能力 [#当前主线视图状态同步能力] * 新增统一 `initialViewState`、`view-state-change`、`getViewState()` 和 `applyViewState()` 协议,面向投屏、远端协同、双栏对比和阅读进度恢复 * 所有标准 renderer loader 自动注册通用 view-state provider,未写专属适配的格式也能记录 / 恢复 renderer、缩放和滚动比例 * PDF 提供页码、页数、缩放、旋转、滚动和导航状态;XMind、Geo、3D、CAD 追加画布 pan、地图中心、相机视角或底层视图快照等高交互状态 * 程序化恢复使用 `source: 'api'` / `action: 'restore'`,并抑制中间滚动和缩放回弹事件,避免操作端和展示端互相触发 * README、中英文使用文档、快速开始和格式能力页已统一说明 view-state、真实 zoom 状态和 PPTX Worker 自托管配置,方便几轮修复后对外口径保持一致 ## 当前主线缩放状态准确性修复 [#当前主线缩放状态准确性修复] * core 的 zoom controller 会订阅 renderer provider 的异步状态变更,首屏自适应、容器 resize 和内部重排后同步抛出真实 `zoom-change` * `getOperationAvailability()` / `operation-availability-change` 会结合当前 `zoomState` 动态计算 `zoomIn`、`zoomOut`、`zoomReset`,各生态组件和自定义工具栏不再拿到静态缩放能力 * PDF、Word/DOCX、DOC 和图片预览修正首屏 fit 后的真实比例、缩放步进和 reset 状态,避免显示默认 `100%` 或点击缩放时来回跳 * 新增 `pnpm verify:zoom-state` 浏览器回归,覆盖 DOCX、PDF 和图片的首屏比例、内部 scale 与工具栏显示一致性 ## `v2.1.9` OFD 资源路径解析加固 [#v219-ofd-资源路径解析加固] * OFD renderer 加固电子发票资源路径归一化和查找逻辑,兼容 `DocumentRes`、`PublicRes`、`BaseLoc`、大小写差异和缺失目录等组合场景 * 修复部分 OFD 文件读取图片资源时因路径解析失败抛出 `Cannot read properties of undefined (reading 'async')`,导致整份文档无法预览的问题 * 缺失或异常资源继续降级跳过,保证可解析页面主体优先展示 ## `v2.1.8` OFD 电子发票兼容与压缩包内嵌预览修复 [#v218-ofd-电子发票兼容与压缩包内嵌预览修复] * OFD renderer 兼容多个并列 `ofd:Fonts`、`ofd:DrawParams`、`ofd:MultiMedias` 资源分组,修复部分电子发票在读取图片资源时抛出 `Cannot read properties of undefined (reading 'format')` 的问题 * OFD 图片资源渲染增加缺失资源兜底,单个资源异常不会中断整份文档正文预览 * PDF renderer 默认静态 `vendor/pdf/pdf.worker.mjs` 不存在或被网关回退成 HTML 时,会自动懒加载包内 PDF.js worker handler 兜底,修复轻量 `@file-viewer/vue3` / `@file-viewer/web` + `@file-viewer/preset-office` 接入时因未复制 viewer assets 导致 `Setting up fake worker failed` 的问题;显式 `options.pdf.workerUrl`、Vite 插件和 `file-viewer-copy-assets` 仍优先使用真实 Worker * 压缩包预览支持隐藏/显示内部文件列表,长文件名自动省略,避免移动端和窄容器下把页面挤出视图 * `@file-viewer/web-full` IIFE 嵌套预览继续使用当前已安装的 renderer / preset 上下文,压缩包内 PDF、Office、图片等文件不再误判为缺失 renderer ## 当前主线 GitHub 曝光与长期运营资产优化 [#当前主线-github-曝光与长期运营资产优化] * README 首屏改为“面向企业后台、内网和私有化系统的纯前端文件预览组件”,把无需服务端转码、Demo、文档、快速开始和支持格式前置,把 206 个扩展名作为可信度证据承接 * 新增 `CONTRIBUTING.md`、`SUPPORT.md`、`SECURITY.md`、`CODE_OF_CONDUCT.md`、`ROADMAP.md`、根 `CHANGELOG.md`、Issue 模板和 PR 模板,方便收集真实业务文件兼容性反馈 * 文档站新增方案对比页,克制说明 File Viewer、服务端转码和 Office Online / 云服务的适用边界 * 新增 `RELEASE_TEMPLATE.md`,沉淀 Release 写法、Topics、Social Preview 和版本发布节奏 * 新增 GitHub Wiki 同步链路,将完整中英文文档以 Wiki 页面保留在 GitHub,和官网文档站形成双入口 ## `v2.1.6` Vite 插件 PDF 资产复制与移动端接入说明修复 [#v216-vite-插件-pdf-资产复制与移动端接入说明修复] * `@file-viewer/vite-plugin` 的依赖解析改为递归锚点发现:在 pnpm / yarn PnP 风格严格依赖场景下,即使业务只直接安装 `@file-viewer/react`、`@file-viewer/preset-office` 和 `@file-viewer/vite-plugin`,插件也能从 preset 依赖链继续定位 `@file-viewer/renderer-pdf` 与 `pdfjs-dist`,正确复制 `vendor/pdf/pdf.worker.mjs`、CMap、WASM 和 standard fonts * 新增插件回归用例,模拟 React/Vite 项目中 renderer 只挂在 preset 依赖下的安装结构,验证 `copyAssets:true` 能在 dev publicDir 中生成完整 PDF 离线资源 * React 快速开始补充手机浏览器、H5 WebView 与 React Native WebView 接入说明,明确容器高度、`100dvh`、安全区、右下角工具栏、内部缩放 provider 和自托管 Worker/WASM 资源的推荐配置 ## `v2.1.5` DOCX Electron 兼容与 Excel 图片滚动层级修复 [#v215-docx-electron-兼容与-excel-图片滚动层级修复] * DOCX Worker 默认改为自动环境检测:HTTP/HTTPS 部署继续启用 Worker,Electron `file://`、`about:`、`data:` 等不安全本地协议会自动回退到主线程解析,避免本地预览长时间等待 Worker 握手;显式 `options.docx.worker: true / false` 仍拥有最高优先级 * DOCX Worker 默认超时调整为 5000ms,静态资源路径、MIME、CSP 或 WebView 不兼容时更快回退,减少用户误判为页面卡死的等待时间 * Excel / XLSX 图片浮层限制在真实单元格内容区,并为右侧/底部滚动条预留安全交互区域,修复图片覆盖表格滚动条导致滚动困难的问题 ## `v2.1.4` 文档首页专业化与 IIFE 按格式异步加载 [#v214-文档首页专业化与-iife-按格式异步加载] * 文档站首页重构为能力驱动入口,首屏突出浏览器端文件预览基础设施、多格式覆盖、统一交互、模块化装配、离线资源和企业部署能力,避免只围绕快速开始展开 * 中英文文档首页同步新增核心能力区,说明高还原格式链路、按需性能策略、搜索/缩放/打印/导出/水印等统一交互,以及公网、内网、Docker、Cloudflare Pages、Release 包和私有 CDN 的交付边界 * `@file-viewer/web-full` IIFE 首包改为只注册 Custom Element、controller 和 lazy full preset;PDF、Word、Excel、CAD、Typst、压缩包等重型 renderer 会在命中文件类型时异步加载 `dist/renderers/*.iife.js` * Worker、WASM、字体、PDF cMap、CAD、Typst、Archive、Docx、Excel 和 Draw\.io 离线资源继续按脚本 URL 自动解析,保持 CDN 与企业自托管一致体验 ## `v2.1.3` CDN 全量接入与生态 full 包 [#v213-cdn-全量接入与生态-full-包] * 新增 `@file-viewer/web-full`、`@file-viewer/vue3-full`、`@file-viewer/vue2.7-full`、`@file-viewer/vue2.6-full`、`@file-viewer/react-full`、`@file-viewer/react-legacy-full`、`@file-viewer/jquery-full` 和 `@file-viewer/svelte-full`,面向“先验收完整能力,再按业务边界裁剪”的快速接入场景 * `@file-viewer/web-full` 提供 CDN / script 标签完整格式入口,IIFE 包会根据脚本地址自动定位随包分发的 Worker、WASM、字体、PDF cMap、CAD、Typst、Archive、Docx、Excel 和 Draw\.io 离线资源,适合公网 CDN 与企业自托管两种模式 * 保留原有轻量组件包与 `preset-lite` / `preset-office` / `preset-engineering` / `preset-all` 的按需组合模式;文档和 README 前置说明“轻组件 + preset / renderer”的推荐边界,避免把 full 包误用为所有业务的默认选择 * Vanilla JS 快速开始补齐无组件命令式 `mountViewer` 示例;Vue3、Vue2.7、Vue2.6、React、React Legacy、Svelte、jQuery 的快速开始均补齐 full 包与按需包两条路径 * 生态包校验扩展到 50 个发布目标,覆盖标准组件、完整 full 包、核心、renderer、preset、Vite 插件与历史兼容 alias;发布链路同步构建 Demo、官网、文档站、开源总仓和 npm ## `v2.1.2` 压缩包内嵌预览、移动端 PDF 与安装口径修复 [#v212-压缩包内嵌预览移动端-pdf-与安装口径修复] * 压缩包内嵌 PDF / Office / 图片等文件预览会清理父级压缩包的 `url` / `streamUrl`,避免内部 PDF 误读取外层 `.zip` / `.rar` 流导致 `Invalid PDF structure` 或 `Bad FCHECK in flate stream` * 移动端 PDF 预览在窄屏默认收起页侧边栏并压缩工具栏高度,避免导航面板遮挡页面主体;显式 `options.pdf.defaultNavigationVisible` 仍可覆盖默认行为 * 快速开始、生态总览和 README 将“轻组件包 + preset / renderer 格式能力层”的安装边界前置说明,明确 `@file-viewer/vue3` 等组件包最轻,`preset-all` 是完整 Demo / 内部全格式入口而非所有业务默认选择 * 发布前回归覆盖 `archive` 嵌套渲染上下文、core preset 自动装配、文档构建、Demo 构建、官网构建、离线资源校验、安装体积预算和冷安装时间;`vue3 + preset-all` 最重冷安装目标通过 * 全线生态包、Demo、文档站、官网和开源总仓同步推进到 `2.1.2` ## `v2.1.1` GitHub issue 回归修复与发布同步 [#v211-github-issue-回归修复与发布同步] * `@file-viewer/vite-plugin` 新增 preset 自动发现与默认 HTML 注入;安装 `@file-viewer/vue3` 等组件包并安装 `@file-viewer/preset-office` / `preset-engineering` 后,框架组件可通过 `autoRenderers` 自动获得对应预览能力,仍保留 `inject:false`、`autoRenderers:false` 和 `rendererMode:'replace'` 的手动控制路径 * core 缺失 renderer 状态改为区分“支持矩阵内但未装配”和“真正不支持”:如 `.pdf` 未装配时提示安装 `@file-viewer/preset-office` 或 `@file-viewer/renderer-pdf`,避免用户误解为产品不支持该格式 * Markdown 预览自动剥离文件开头 YAML Frontmatter,避免元数据被当作正文渲染,同时保留正文中的普通分隔线 * PDF 默认 Worker、cMap、WASM 和标准字体资源改为站点根路径解析,兼容 Vite / Vue Router / React Router 等深层路由部署 * Excel / XLSX worker 将图片 drawing anchor 纳入虚拟表格尺寸计算,修复图片位于数据区下方时无法继续向下滚动的问题 * 工具栏新增 `toolbar.items` 与 `toolbar.permissions`,同时保留 `beforeOperation` / `toolbar.beforeOperation` 作为异步鉴权和确认拦截点 * 全线生态包、Demo、文档站、官网和公开总仓同步推进到 `2.1.1` ## `v2.1.0` 模块化架构与文档门户专业化 [#v210-模块化架构与文档门户专业化] * 全仓 workspace、标准组件包、renderer、preset、兼容 alias、Demo、官网和文档站版本统一推进到 `2.1.0` * 对外重点明确为模块化架构:`@file-viewer/core` 负责底层协议和统一 API,重型格式能力进入独立 renderer,`preset-lite` / `preset-office` / `preset-engineering` / `preset-all` 按产品形态组合,各生态组件保持原生体验 * README 头部补齐品牌图标、GitHub / npm / Docs / Demo / Release / Docker / License / 格式矩阵 badge,并把 Demo GIF 前置,降低用户理解成本 * README 与文档站补齐最小化引入和组合引入的详细步骤,说明 `@file-viewer/vite-plugin`、`formats`、`preset`、`copyAssets`、`virtual:file-viewer-renderers`、`builtinRenderers:'none'` 和 `rendererMode:'replace'` 的推荐搭配 * 文档站首页移除嵌入 Demo 的 iframe,改为 GIF 展示、模块化接入路径和更专业的文档导览;官网 `file-viewer.app` 改为嵌入 `doc.file-viewer.app`,让门户和文档站关系更紧密 * 对外 npm 生态口径更新为 50 个发布目标:45 个标准组件/完整 full 包/核心/renderer/preset/工程插件包 + 5 个历史兼容 alias ## 当前主线 XMind、EDA 版图与表格列宽体验补齐 [#当前主线-xmindeda-版图与表格列宽体验补齐] * 新增 PSD 高保真图层预览,`@file-viewer/renderer-data` 在命中 `.psd` 时才按需加载 `ag-psd`,支持图层选择显隐、画布重绘、统一缩放、主题隔离和 HTML 导出边界说明 * 新增 Mermaid / PlantUML 绘图预览,`@file-viewer/renderer-drawing` 在命中 `.mermaid` / `.mmd` / `.plantuml` / `.puml` 时才分别加载官方 Mermaid renderer、`plantuml-encoder` 与 Panzoom;PlantUML 默认离线源码预览,需要完整服务端 SVG 时可通过 `options.drawing.plantumlServerUrl` 指向自托管服务 * 新增 Git patch 和 Git bundle 预览,`@file-viewer/renderer-text` 对 `.patch` 按需加载 `diff2html` 输出左右比对,对 `.bundle` / `.bdl` 解析 refs、提交历史、文件树和可读 blob 内容,并在浏览器端还原常规 OFS_DELTA / REF_DELTA 对象 * UMD 电子书从 core 迁移到 `@file-viewer/renderer-epub`,与 EPUB 共用电子书 renderer 包;`@file-viewer/core` 运行时依赖归零,`pako` 仅在打开 UMD / Git bundle 等相关 renderer chunk 时加载 * 支持格式矩阵更新为 206 个扩展名、24 条预览链路;Demo 新增 PSD、Mermaid、PlantUML、patch 和 git bundle 示例,Vite 插件、bundle budget、组件 README 与文档站口径同步 * XMind 画布交互切换为轻量成熟的 `@panzoom/panzoom`,保留 `@ljheee/xmind-parser` 的 XMind 8 XML / XMind 2020+ JSON 解析链路,拖拽平移、节点起手拖拽、移动端双指缩放、滚轮锚点缩放、键盘平移、适配画布和 toolbar 状态同步由统一 Panzoom 状态驱动;浏览器 smoke 已加入真实鼠标拖拽断言 * `@file-viewer/eda-layout` 新增 OASIS 可读文本夹具解析,OAS/OASIS demo 不再只是结构提示,能够在浏览器里输出 SVG 版图;真实 SEMI 二进制 OASIS 仍保持安全结构索引、可读字符串、实体候选和诊断边界,后续完整几何继续走独立 WASM/增量渲染内核路线 * 新增 `@file-viewer/renderer-presentation` 独立 renderer 包,基于 `@file-viewer/pptx` 提供 PPTX / PPTM / POTX / POTM / PPSX / PPSM 按需预览、缩放、打印和 HTML 导出;`@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 已优先聚合该包,ODP 继续走 OpenDocument 兼容链路 * `@file-viewer/core` 移除 `@file-viewer/pptx` 直接依赖和内置 PPTX handler,PowerPoint 完整预览统一通过 `@file-viewer/renderer-presentation` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 37 降到 36 * 新增 `@file-viewer/renderer-word` 独立 renderer 包,承接 DOCX / DOCM / DOTX / DOTM、DOC / DOT、RTF 和 ODT 预览链路;`@file-viewer/core` 移除 `@file-viewer/docx`、`msdoc-viewer`、`rtf.js`、`linkedom` 和 `@xmldom/xmldom` 直接依赖,Word 完整预览统一通过 `@file-viewer/renderer-word` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 36 降到 31 * XMind 已从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@ljheee/xmind-parser`;完整脑图预览统一由 `@file-viewer/renderer-mindmap` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 31 降到 30 * 地理数据已从 core 兼容入口中移出,`@file-viewer/core` 不再默认安装 `@tmcw/togeojson`、`shpjs`、`maplibre-gl` 和 `proj4`;GeoJSON / KML / GPX / SHP 预览统一由 `@file-viewer/renderer-geo` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 30 降到 28 * HEIC / HEIF 转换能力已从 core 轻量图片入口中移出,`@file-viewer/core` 不再默认安装 `heic2any`;普通图片仍保留浏览器原生预览,HEIC / HEIF 和完整图片链路统一由 `@file-viewer/renderer-image` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 28 降到 27 * Vue3 原生组件渲染桥接层改为按当前 `options.renderers`、`options.rendererMode` 和 `options.builtinRenderers` 创建临时 renderer registry,`@file-viewer/preset-all` / 独立 renderer 包会在组件路径真实生效,避免 XMind、Geo、HEIC 等已从 core 移出的格式在 Demo 中误显示“不支持” * 新增 `@file-viewer/renderer-drawing` 独立 renderer 包,覆盖 Draw\.io / diagrams.net 离线 viewer、Excalidraw rough.js 只读 SVG 兜底、统一缩放、打印和 HTML 导出,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合 * 新增 `@file-viewer/renderer-3d` 独立 renderer 包,基于 Three.js loaders 承接 GLTF/GLB、OBJ、STL、PLY、FBX、DAE、3DS、3MF、USD/USDZ、点云和 VTK 等 WebGL 预览,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合 * 新增 `@file-viewer/renderer-data` 独立 renderer 包,承接字体、PSD、AI/EPS、SQLite、Parquet、Avro、WASM 和 WebArchive 的安全结构预览,SQLite WASM 由 `@file-viewer/vite-plugin` 复制到离线 assets * 新增 `@file-viewer/renderer-eda` 独立 renderer 包,承接 OLB、DRA、GDSII、OASIS 结构预览;标准 GDSII 可用纯前端记录解析生成 SVG 快速版图,大元素集会自动切到 WebGL canvas,OASIS / Cadence 高保真几何继续按独立 WASM 内核路线维护 * 新增 `@file-viewer/eda-layout` 与 `@file-viewer/eda-orcad` 两个 EDA engine package;GDSII/OASIS 版图底层能力、OrCAD/Allegro 二进制检查能力从 UI renderer 中拆出,GDSII WebGL typed-array 批次已有独立门禁,后续 OASIS WASM 或逐步 TS 移植可以独立发布、独立回归 * 复核 XMind、GDSII/OASIS、OLB/DRA 等新增复杂格式的公开生态与 WASM/手写解析路线,明确 GDSII 是当前正式快速预览,OASIS 文本夹具可真实出图,真实二进制 OASIS/OLB/DRA 仍属于结构预览和后续独立 WASM 内核路线;同时把 XMind `pan` 写入 smoke matrix 显式断言,真实浏览器 smoke 已覆盖 Pointer 与真实鼠标拖拽路径 * 按需渲染架构计划补齐为可执行路线图,明确轻 core、独立 renderer、preset 编排、Vite 插件自动装配、renderer 交付契约、core 依赖预算和终态验收门禁;新增 `verify:core-dependency-budget`、`verify:renderer-contracts`、`verify:renderer-assets`、`verify:install-budget` 与 `verify:bundle-budget`,后续以清理 core 直接重依赖和守住首屏入口体积为 2.x 主治理线 * 支持格式矩阵保持 206 个扩展名、24 条预览链路,新增 XMind 脑图、Mermaid / PlantUML、Git patch / bundle 和 PSD 图层预览,并将 EDA 安全结构索引扩展到 GDSII / OASIS 版图文件;`brep` 进入 3D 工程模型入口 * `.xmind` 基于 `@ljheee/xmind-parser` 离线解析 XMind 8 XML 与 XMind 2020+ JSON 包结构,支持多 sheet、节点、标签、备注、链接、标记、图片、目录树、Panzoom 拖拽平移、移动端双指缩放、适配画布、搜索、缩放、打印和 HTML 导出 * 优化 XMind 画布平移体验,使用 Panzoom 替代脆弱的手写输入状态机,支持移动端 pinch zoom、Ctrl/Command 滚轮锚点缩放、键盘方向键平移和双击适配视图,拖拽中禁用链接命中并禁用浏览器原生拖图/拖链接,边界约束改为画布式保留可见边缘 * XMind 浏览器 smoke 已增加 Pointer、节点起手、滚轮平移和真实鼠标拖拽断言 * XMind 平移、目录定位和键盘方向键移动后会同步通知统一缩放 toolbar,外部 `resetZoom()` / `getZoomState()` 能正确感知“已平移但比例未变化”的状态 * XMind 官方 Demo 样例已通过真实浏览器回归:`.xmind` 能由 `@file-viewer/renderer-mindmap` 正常接管,拖拽后画布 transform 发生平移变化,证明组件层 preset 装配和 renderer 内部 pan 交互同时生效;浏览器冒烟脚本也会对 `.xmind` 执行 PointerEvent 拖拽断言 * XMind 增加 ResizeObserver 视口适配策略:首次打开和宿主容器尺寸变化会自动适配画布,用户手动拖拽、滚轮或缩放后保留当前视角,只做安全边界校正,避免脑图在移动端、嵌入容器和响应式布局中“拖不动”或 resize 后视角丢失 * 代码与 Markdown 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `highlight.js` 和 `marked`;完整文本预览统一由 `@file-viewer/renderer-text` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 27 降到 25,Phase 3 依赖预算从 10 降到 8 * 音视频预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `hls.js` 和 `@tonejs/midi`;MP3/WAV/OGG/MIDI/MP4/WEBM/HLS 完整媒体能力统一由 `@file-viewer/renderer-media` 或 `@file-viewer/preset-all` 装配,core 直接渲染依赖从 25 降到 23,Phase 3 依赖预算从 8 降到 6 * 3D 模型与绘图预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `three`、`@excalidraw/excalidraw` 和 `roughjs`;GLB/GLTF/STL/OBJ/FBX/DAE/3MF/VTK 等模型由 `@file-viewer/renderer-3d` 装配,Draw\.io / Excalidraw / Mermaid / PlantUML 由 `@file-viewer/renderer-drawing` 装配,core 直接渲染依赖从 23 降到 20,Phase 3 依赖预算从 6 降到 3 * 压缩包、邮件和 EPUB 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `libarchive.js`、`postal-mime`、`@kenjiuno/msgreader` 和 `epubjs`;Archive / Email / EPUB 完整能力统一由 `@file-viewer/renderer-archive`、`@file-viewer/renderer-email`、`@file-viewer/renderer-epub` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 20 降到 16,Phase 3 依赖预算从 3 降到 0 * 数据资产与 EDA 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `ag-psd`、`sql.js`、`hyparquet`、`avsc` 和 `cfb`;PSD / SQLite / Parquet / Avro / OLB / DRA / GDSII / OASIS 完整能力统一由 `@file-viewer/renderer-data`、`@file-viewer/renderer-eda` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 16 降到 11,Phase 4 依赖预算归零 * PDF 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `pdfjs-dist`;PDF 页面渲染、导航、目录、搜索、缩放、打印和导出统一由 `@file-viewer/renderer-pdf` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 11 降到 10,Phase 2 依赖预算从 10 降到 9 * OFD 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `jszip`、`ofd-xml-parser` 和 DLTech21/ofd.js vendor;OFD 页面渲染、缩放、打印和导出统一由 `@file-viewer/renderer-ofd` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 10 降到 8,Phase 2 依赖预算从 9 降到 7 * Typst 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@myriaddreamin/typst.ts`、`@myriaddreamin/typst-ts-renderer` 和 `@myriaddreamin/typst-ts-web-compiler`;Typst 源文件编译、按页 SVG 渲染、缩放、打印和导出统一由 `@file-viewer/renderer-typst` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 8 降到 5,Phase 2 依赖预算从 7 降到 4 * CAD 预览从 core 兼容入口中彻底移出,`@file-viewer/core` 不再默认安装 `@flyfish-dev/cad-viewer`;DWG / DXF / DWF / DWFx / XPS 完整预览统一由 `@file-viewer/renderer-cad` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 5 降到 4,Phase 2 依赖预算从 4 降到 3 * Spreadsheet 预览从 core 兼容入口中彻底移出,新增 `@file-viewer/renderer-spreadsheet` 独立 renderer 包承接 XLSX / XLSM / XLSB / XLS / CSV / ODS / FODS / Numbers 等表格格式;`@file-viewer/core` 不再默认安装 `styled-exceljs`、`e-virt-table` 和 `tinycolor2`,完整表格能力统一由 `@file-viewer/renderer-spreadsheet` 或 `@file-viewer/preset-all` 装配,core 直接运行时依赖从 4 降到 1,Phase 2 依赖预算从 3 降到 0 * `.gds` 新增标准 GDSII 记录解析、SVG 版图预览和大元素集 WebGL canvas,能够展示 structure、boundary、path、text、reference、层信息和坐标边界;`.oas`、`.oasis` 文本夹具可生成 SVG 版图,真实 SEMI 二进制 OASIS 保持纯前端安全结构索引、可读字符串、实体候选、二进制线索和诊断,避免把专业 EDA 文件误当普通文本或空白二进制 * 邮件预览迁移为 `@file-viewer/renderer-email` 独立 renderer 包,继续支持 EML / MSG / MBOX、正文/头信息切换、附件下载和附件嵌套预览,并由 `@file-viewer/preset-all` 自动聚合 * OFD 预览迁移为 `@file-viewer/renderer-ofd` 独立 renderer 包,继续基于 `DLTech21/ofd.js` 的纯前端源码链路解析和页面渲染,vendor 随包离线分发,并由 `@file-viewer/preset-all` 与 `@file-viewer/vite-plugin` 自动聚合 * EPUB 预览迁移为 `@file-viewer/renderer-epub` 独立 renderer 包,继续使用 `epubjs` 提供目录、滚动阅读、章节跳转和阅读进度,并由 `@file-viewer/preset-all` 自动聚合 * 代码与 Markdown 预览迁移为 `@file-viewer/renderer-text` 独立 renderer 包,继续使用按语言动态加载的 `highlight.js` 和 `marked`,并由 `@file-viewer/preset-all` 自动聚合 * 图片预览迁移为 `@file-viewer/renderer-image` 独立 renderer 包,普通图片继续使用浏览器原生解码,HEIC / HEIF 只在命中格式时按需加载 `heic2any`,并由 `@file-viewer/preset-all` 自动聚合 * 音视频预览迁移为 `@file-viewer/renderer-media` 独立 renderer 包,MP4 / WebM / 常见音频继续使用原生控件,HLS 和 MIDI 只在命中格式时按需加载 `hls.js` / `@tonejs/midi`,并由 `@file-viewer/preset-all` 自动聚合 * 地理数据预览迁移为 `@file-viewer/renderer-geo` 独立 renderer 包,GeoJSON 直接读取,KML / GPX 按需加载 `@tmcw/togeojson`,SHP 按需加载 `shpjs`,地图叠加层和 CRS 转换按需加载 `maplibre-gl` / `proj4`,并由 `@file-viewer/preset-all` 自动聚合 * 新增 `@file-viewer/vite-plugin` 工程化入口,支持按 `formats` 自动生成 `virtual:file-viewer-renderers`、renderer chunk 分组、缺失 renderer 提示,并复制 PDF/CAD/Typst/Archive 离线 worker/WASM/vendor 资源和部署 manifest * `@file-viewer/vite-plugin` 新增 `scan: true` 源码 hint 自动装配能力,可从 `fileViewerFormats` / `fileViewerRenderers` / `data-file-viewer-formats` / 上传 `accept` 声明提取格式并选择对应 renderer;新增 `verify:vite-plugin-auto-scan` 防止自动化装配链路回退 * 新增 `@file-viewer/preset-lite`、`@file-viewer/preset-office` 和 `@file-viewer/preset-engineering` 三个标准 preset 包;`@file-viewer/vite-plugin` 支持 `preset: 'lite' | 'office' | 'engineering' | 'all'`,会导入对应 `@file-viewer/preset-*` 包,并可继续用 `formats` 补充 preset 外 renderer,兼容 pnpm 严格依赖模型 * `verify:renderer-standalone-smoke` 从 PDF-only 升级为全独立 renderer plugin 门禁,使用本地 tarball 构造隔离业务项目,安装 core、Vite 插件、19 个 renderer plugin 以及本地依赖闭包,逐个验证 renderer 注册、handler 挂载、Vite selection 映射和 virtual module 不误引入无关 renderer 包 * 标准组件 README 与开源总仓 README 新增“工程级按需 renderer 装配”双语片段,统一说明 `@file-viewer/vite-plugin`、`virtual:file-viewer-renderers`、`builtinRenderers:'none'`、`rendererMode:'replace'`、`scan:true`、`copyAssets:true` 和 `@file-viewer/preset-all` 的推荐使用边界,并由 `verify:ecosystem-readmes` 纳入自动校验 * STEP / IGES / IFC / 3DM / BREP 等重型工程格式完成浏览器 WASM 路线调研,并新增 `@file-viewer/geometry-engine` 独立边界包维护签名识别、推荐内核和转换说明;OpenCascade、web-ifc、rhino3dm 等重 WASM 不进入 core 首屏链路 * 表格预览新增 `options.spreadsheet.resizableColumns` 开关,默认关闭以保持历史交互兼容;官方 Demo 默认开启,方便客户拖拽表头边界查看被截断的长文本 * Demo 新增 `mindmap.xmind`、`layout.gds`、`layout.oas`、`layout.oasis` 示例,并将样例选择器补充为脑图与绘图、邮件与 EDA 等更清晰分组 ## `v2.0.11` Vanilla JS 原生组件增强版 [#v2011-vanilla-js-原生组件增强版] * 全生态包版本同步推进到 `2.0.11`,Demo、官网、文档站、组件 README、开源总仓库和 npm 发布统一使用最新 Vanilla JS 入口 * `@file-viewer/web` 新增 `` 原生 Web Component,支持 `src/url`、`filename/name`、`type`、`size`、`theme`、`toolbar`、`toolbar-position`、`watermark`、`search`、`options` 等属性,并暴露完整 controller 实例方法 * IIFE script 标签包会自动注册 Custom Element,同时继续暴露 `window.FlyfishFileViewerWeb.mountViewer`,兼顾无构建工具页面和完全命令式接入场景 * 组件 Demo 新增 Custom Element 独立页面,并把浏览器 smoke 扩展到原生元素、IIFE 自动注册、React、Vue3、jQuery、Svelte 和手写 JS 入口 * 文档站、官网首页和 README 将纯 JS 默认推荐路径更新为 Web Component,`mountViewer` 作为高级 controller API 保留 ## `v2.0.10` DOCX 自研渲染引擎稳定版 [#v2010-docx-自研渲染引擎稳定版] * 全生态包版本同步推进到 `2.0.10`,Demo、组件 Demo、官网、文档站和开源总仓库统一使用当前 DOCX 主链路 * `@file-viewer/core` 继续使用自研 `@file-viewer/docx@0.3.12`,默认 Worker 解析、连续流式阅读、目录字段缓存、异步分批渲染和离线 `workerUrl` / `workerJsZipUrl` 资源配置 * DOCX 默认保持流式布局,避免复杂目录、长表格、制表符、样式继承和中文正式文档在视觉分页中被拆坏;需要页式效果的业务仍可显式开启 `options.docx.visualPagination` * 开源 README、文档站、组件 README、Demo 样例与发布产物统一以当前 DOCX 能力为准,便于客户直接升级验证 ## `v2.0.9` 生态文档与定制能力完善版本 [#v209-生态文档与定制能力完善版本] * 文档站、README 和各生态组件 README 全量补齐实际支持的 props / options / events / controller API,覆盖 Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte、core 与兼容 alias 包 * 工具栏定制能力文档化,统一说明 `options.toolbar`、`toolbar.beforeOperation`、`toolbar.items`、自定义按钮、隐藏默认工具栏和外部自定义工具栏的最佳实践 * 官网首页补充多框架快速接入代码切换板块,帮助用户在 Vanilla JS / Pure Web、Vue、React、Svelte、jQuery 和 core API 之间快速定位接入方式 * 生态发布口径同步刷新到 `2.0.9`,继续保持 core 纯 TypeScript 底座、各框架组件独立实现、离线资源随包分发和生产级 demo / 文档站 / 官网一体上线 ## 当前主线 [#当前主线] ### 当前主线 DOCX 自研渲染引擎接入 [#当前主线-docx-自研渲染引擎接入] * DOCX / DOCM / DOTX / DOTM 渲染切换为自研 `@file-viewer/docx`,默认启用 Worker ZIP/XML 解析、真实浏览器 DOM 连续流式渲染、目录字段缓存和异步分批渲染;页式预览改为 `options.docx.visualPagination: true` 显式开启 * 新增 `options.docx.workerJsZipUrl`,与 `options.docx.workerUrl` 一起支持完全离线部署;viewer assets 会复制 `vendor/docx/docx.worker.js` 和 `vendor/docx/jszip.min.js` * `options.docx.worker` 默认开启,仅在 CSP 或宿主环境禁用 Worker 时需要关闭;默认超时提升到 120000ms,降低大文档误回退概率 * 文档站、README、格式矩阵和纯 JS 离线接入说明同步改为 `@file-viewer/docx` 口径 ### 当前主线 生态接入文档全量对齐 [#当前主线-生态接入文档全量对齐] * 新增 [生态组件总览](/zh/guide/ecosystem),集中说明 `@file-viewer/core`、`@file-viewer/pptx`、Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 和历史兼容包的选型边界 * 文档站导航、快速开始、Vue2/React/Pure Web 接入、组件用法、FAQ、发布分发和开发发版说明统一改为 `@file-viewer/*` 标准包名优先 * 补齐 Svelte 组件/action、jQuery 插件、Pure Web script 标签、Core 自定义接入、离线 viewer assets 和统一 controller API 示例 * 修正 React 文档中的事件参数为标准 `onEvent`,并明确 React Legacy、Vue2.6、PPTX 引擎和离线资源复制流程 ### 当前主线 全格式浏览器冒烟与静态资源稳定性修复 [#当前主线-全格式浏览器冒烟与静态资源稳定性修复] * 修复 3D 模型、OFD、EPUB、UMD、绘图和 CAD 等渲染器的隐藏 loading 状态在部分浏览器/CSS 组合下仍可见的问题,避免预览完成后继续显示“正在解析” * Draw\.io 默认切换为随 viewer assets 分发的官方 diagrams.net 离线 viewer,加载超时后自动切换本地 SVG 安全预览,保证 `drawio` / `dio` 样例不会因 viewer 初始化卡住而长期 loading * PDF 预览新增 `options.pdf.thumbnails`,页面导航可切换为真实页面缩略图;缩略图使用 IntersectionObserver 按可见区域懒渲染,避免大文档一次性生成所有 canvas * PDF 视图会在页面初始化、缩放、旋转和渲染后写回传统 `px` 页面尺寸,兼容不支持 CSS `round()` 的 360 极速、华为浏览器等 Chromium 分支 * Typst compiler / renderer WASM 和默认字体资产改为随 viewer assets 本地分发,并新增 `options.typst.fontAssetsUrl` / `options.typst.renderTimeoutMs`;默认加载 / 编译超时提升到 180 秒,浏览器端始终走真实 SVG 预览链路,不再用源码视图冒充成功,也不再为默认字体访问公共 CDN * Cloudflare Pages 部署脚本会对超过单文件限制的 Typst compiler WASM 自动做 Brotli 预压缩并写入 `_headers`,补齐 `Content-Encoding: br`、`Vary: Accept-Encoding`、WASM MIME 和长期缓存策略;新增 `pnpm verify:cloudflare-compression` 用于上线后验证官网、文档站、Demo 和 Typst WASM 的 Cloudflare 压缩响应 * 运行时不再提供公共 CDN 或第三方在线资源 fallback;Typst 本地 WASM 或字体目录不可用时会显示明确部署错误,Draw\.io 默认走官方离线 viewer 并在异常时回退内置 SVG,适合企业内网和纯离线部署 * PDF.js worker、CMap、WASM 和 standard fonts 默认随 viewer assets 分发到 `vendor/pdf/`,构建脚本会同步复制并校验,避免 PDF 预览隐式访问公网静态资源 * SQLite 预览默认使用 viewer assets 中的 `wasm/data/sql-wasm.wasm`,构建脚本同步复制并校验 sql.js WASM,减少移动端 WebView、本地服务器和 CSP 环境下的加载不确定性 * PDF 样式注入会去除 PDF.js 内置外部图片引用,避免静态产物部署时因 `images/shadow.png` / `loading-icon.gif` 缺失导致 404 或控制台噪声 * 新增全量 demo sample matrix 浏览器冒烟,逐一打开 `example/` 下 107 个样例文件;本轮已在 dev server 和静态 dist 产物中完成真实浏览器验证 ### `v2.0.1` 架构重构与全生态 2.x 起始版本 [#v201-架构重构与全生态-2x-起始版本] * 全线 npm 包、workspace 依赖、Docker 镜像和开源 release 包从 `2.0.1` 重新起步,用大版本号明确标识 core / component 架构重构带来的兼容边界变化 * `@file-viewer/core` 继续保持纯 TypeScript、框架无关的底层能力包;Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 等标准组件包只依赖 core,各自提供原生集成体验 * 清理旧独立页面实现和历史过渡口径,对外文档统一强调原生组件与纯 Web API 是核心集成路径 * 开源总仓库产物命名切换为 `file-viewer-v2-*`,同时发布 2.x npm tarball、Demo、Component Demo、文档站静态产物和库 dist 包,避免继续暴露旧 `file-viewer-v3-*` 产物线 * 文档、README、分发说明、Docker 部署说明和生态验收清单同步刷新到 2.x 版本口径,后续新增能力都在 2.x 线上连续演进 ### 当前主线 统一缩放工具栏 [#当前主线-统一缩放工具栏] * `options.toolbar.zoom` 新增统一缩放按钮显示控制,默认开启;按钮是否真正展示仍由当前渲染链路的内部缩放 provider 决定,避免对虚拟表格、canvas、PDF 文本层和 CAD 交互做宿主级 CSS 强缩放 * 组件 ref 新增 `zoomIn()`、`zoomOut()`、`resetZoom()` 和 `getZoomState()`,外部自定义工具栏可以通过标准 API 控制缩放;`operation-availability-change` 同步返回 `zoom`、`zoomIn`、`zoomOut` 和 `zoomReset`,`zoom-change` 回传最终比例文本 * PDF、DOCX、PPTX、Excel 虚拟表格、图片、CAD、OFD、Typst、Markdown、代码和 Excalidraw / draw\.io 绘图链路接入渲染器内部缩放逻辑;缩放操作同样进入 `options.beforeOperation` / `toolbar.beforeOperation` 前置校验 ### `v1.0.26` Vue3 npm 入口类型声明修复版本 [#v1026-vue3-npm-入口类型声明修复版本] * 修复 `@flyfish-group/file-viewer3@1.0.25` 在发布前被 Demo 构建覆盖 `dist` 后,npm 包缺少 `dist/src/package/index.d.ts`,导致 TypeScript 项目出现 `TS2307: Cannot find module '@flyfish-group/file-viewer3' or its corresponding type declarations` 的问题 * Vue3 标准组件包 使用包内 `prepublishOnly` 发布前保护,根包只保留 monorepo 编排脚本,阻止 Demo HTML 产物误进入组件库 npm 包 * 非 scoped 包 `file-viewer3` 同步发布 `1.0.26`,继续作为 `@flyfish-group/file-viewer3` 的兼容 alias 使用;开源总仓库只保留一份 scoped v3 tarball,避免重复占用存储 * 支持格式矩阵补齐到 194 个扩展名、23 条预览链路,新增 RTF/ODT/ODP、MBOX、GeoJSON/KML/GPX/SHP、AVIF/ICO/HEIC/HEIF/JXL、WEBM/M3U8、MIDI、JSONC/JSON5/IPYNB/TOML/Proto/HCL/TeX/Graphviz/HTTP/Ruby/Swift/Kotlin/React 片段,以及字体、PSD、AI/EPS、SQLite、WASM、Parquet、Avro、WebArchive 等资产/数据预览入口 ### `v1.0.25` 移动端压缩包与表格体验修复版本 [#v1025-移动端压缩包与表格体验修复版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.25`、Vue2 包 `@flyfish-group/file-viewer@1.0.25`、React 包 `@flyfish-group/file-viewer-react@1.0.25` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.25` 继续保持连续版本 * 压缩包预览迁移为 `@file-viewer/renderer-archive` 独立 renderer,并保留 Worker 探测、初始化超时、静态 Worker/WASM 路径和 ZIP/TAR/GZIP 兼容模式;手机 WebView、本地临时服务器、MIME 或 CSP 导致 `libarchive.js` Worker 卡住时,会自动降级,避免一直停留在 loading * `options.archive` 新增 `wasmUrl` 和 `workerTimeoutMs` 说明;普通私有化部署不再需要写死 `workerUrl`,只有静态目录或 WASM 路径特殊时才需要显式指定 * 移动端 Excel / XLS 预览把工作表名称移到表格上方的横向可滚动标签栏,当前工作表自动滚入可见区域,解决手机上 sheet 名称藏在底部角落、需要技巧才能看到的问题 * Excel / XLS 多 sheet 场景下,工作表标签改为按内容宽度展示并横向滚动,避免按整体宽度平均压缩导致 sheet 名称完全看不清 * Excel / XLS 静态 Worker 改为显式 opt-in,默认使用同一套主线程解析器,避免本地服务器、手机 WebView、MIME 或 CSP 环境下停在 Worker 初始化阶段 * DOCX 默认采用真实浏览器 DOM 连续渲染;`docx.worker` 和 `docx.progressive` 保持默认开启以提升大文档响应,`docx.visualPagination` 改为显式 opt-in,避免复杂目录、长表格、制表符和样式继承被分页拆坏 * README、文档站、React / 纯 JS 接入文档、开源 release 包和 workspace 依赖同步刷新到 `1.0.25` ### 当前主线 Demo 富样式公开样例升级 [#当前主线-demo-富样式公开样例升级] * DOCX 渲染链路下沉到 `@file-viewer/core`,移除 Vue3 本地 Word vendor 入口;所有标准组件包共享同一套 DOCX 页面渲染、缩放 provider、打印和 HTML 导出适配器 * DOCX Worker 保留 `options.docx.workerUrl`、`options.docx.workerJsZipUrl` 与 `options.docx.workerTimeout` 兜底,静态资源不可用、CSP/MIME 不兼容或超时后由 DOCX 引擎自动回退 * CAD 渲染器保持在 `@flyfish-dev/cad-viewer` 0.6.4,支持 DWG / DXF / DWF / DWFx / XPS 统一预览;DWG 默认通过独立 Worker 加载 LibreDWG WASM,DWF/DWFx/XPS 使用 native renderer 渲染 W2D/W3D/XPS 图形 * 构建脚本会复制 `libredwg-web.js`、`libredwg-web.wasm`、`dwfv-render.wasm`、`dwg-worker.js` 和 worker 依赖 chunk 到 viewer assets 的 `wasm/cad/` * Demo 补充 Apache Tika `blocks_and_tables.dwf` 与 Autodesk 官方 Viewer 教程的 `House.dwfx`、`RobotArm1.dwfx` 样例,用于分别验证 DWF、DWFx/XPS、W2D/W3D native renderer 和大图纸按需加载体验 * 入口组件在挂载重型渲染器前先释放浏览器绘制帧,确保 Loading 先显示,减少用户误以为页面无响应 * `word.docx` 保持 Basel Convention 公开中文正式文档,覆盖长正文、标题层级、表格、图示、白色纸张和完整打印回归,避免默认 Demo 使用临时生成或过度病态的样例文件 * `ppt.pptx` 与英文 `sample-presentation.pptx` 替换为 NASA Science 公开月球科学战略演示稿,覆盖星云封面、深色引用页、图文混排、正式页眉页脚和 20 页真实专业 PPTX 结构 * `archive.zip` 与 `archive.tar.gz` 内部 DOCX 同步更新为当前公开中文 Word 样例,压缩包内继续预览时也能验证真实文档效果 * 示例来源表、Demo 文档和公开样例 README 同步刷新,避免继续把 Word / PPT 误写成临时生成的 Demo 文件 ### 当前主线 文档比对、搜索定位和 AI 友好结构增强 [#当前主线-文档比对搜索定位和-ai-友好结构增强] * 文档比对页同步滚动改为绑定真实预览滚动容器,并按 scroll ratio 同步左右滚动位置,PDF 内部滚动层、Word 外层滚动层和文本预览都走同一套逻辑 * 文档比对页搜索改为当前聚焦文档的浮层交互,配合成熟图标按钮提供关键词搜索、高亮命中、上一个 / 下一个;避免顶部工具区拥挤,也避免左右两侧同时滚动导致视线丢失 * 文档比对页继续提供行级定位;搜索、定位和文本切片结果会返回行号、页码和锚点上下文,便于业务侧做审计与溯源 * 新增 `options.pdf.toolbar`,可在左右比对等紧凑场景隐藏 PDF 自身页码、缩放、旋转工具栏,避免 PDF 比其他格式多一条顶部导航导致正文错位 * 新增 `options.search`、`searchDocument()`、`clearDocumentSearch()`、`nextSearchResult()`、`previousSearchResult()`、`getSearchState()` 等通用搜索 API;PDF 等特殊渲染器可注册原生搜索提供器,避免通用 DOM 高亮污染文本层或 canvas * 新增 `collectDocumentAnchors()`、`scrollToLine()`、`scrollToAnchor()` 和 `getDocumentTextChunks()`,预览器只提供锚点、文本切片和溯源上下文,不绑定具体 AI 服务,业务侧可基于它做向量化、召回、高亮和来源定位 * 主 Demo 和文档比对 Demo 的搜索浮层统一改用成熟图标按钮,公开文档同步补充文档比对页、搜索定位、PDF 工具栏隐藏、AI 友好结构和溯源定位说明 ### `v1.0.24` CAD native renderer 与构建产物同步版本 [#v1024-cad-native-renderer-与构建产物同步版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.24`、Vue2 包 `@flyfish-group/file-viewer@1.0.24`、React 包 `@flyfish-group/file-viewer-react@1.0.24` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.24` 继续保持连续版本 * CAD 渲染器升级到 `@flyfish-dev/cad-viewer@0.6.2`,DWG / DXF / DWF / DWFx / XPS 统一走成熟 CAD viewer;DWF/DWFx/XPS 使用 `dwf-viewer@0.6.4` native renderer 解析 W2D/W3D/XPS 图形 * 构建脚本新增复制 `dwfv-render.wasm`,与 `libredwg-web.js`、`libredwg-web.wasm`、`dwg-worker.js` 和 worker 依赖 chunk 一起进入 `wasm/cad/`,私有化部署可通过 `options.cad.dwfWasmUrl` 覆盖路径 * 压缩包和邮件附件的嵌套预览同步识别 `dwf`、`dwfx`、`xps`,避免主入口支持 CAD 五类格式而附件链路覆盖不足 * Demo 图纸分组补充 Apache Tika `blocks_and_tables.dwf` 以及 Autodesk 官方 Viewer 教程的 `House.dwfx`、`RobotArm1.dwfx` 样例,便于验证 DWF、DWFx/XPS、多页结构、W2D/W3D 图形、视图适配和按需加载体验 * README、文档站、React / 纯 JS README、入口缓存策略、开源 release 包和 workspace 依赖同步刷新到 `1.0.24` ### `v1.0.22` PPTX 兼容性修复与连续发布版本 [#v1022-pptx-兼容性修复与连续发布版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.22`、Vue2 包 `@flyfish-group/file-viewer@1.0.22`、React 包 `@flyfish-group/file-viewer-react@1.0.22` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.22` 继续保持连续版本 * 修复部分客户 PPTX 无法打开的问题,兼容缺少 `docProps/app.xml` 的演示文稿,默认按现代 Office 版本降级解析 * PPTX OpenXML 关系解析改为通用路径解析,支持 relationship 单对象 / 数组 / 缺失三种形态,并按 `presentation.xml` 真实 slide 顺序渲染 * 增强 slide / layout / master / theme / diagram 关系读取容错,缺失可选部件时降级渲染当前页内容,不再因空指针导致整份 PPTX 白屏 * README、文档站、React / 纯 JS README、入口缓存策略、开源 release 包和 workspace 依赖同步刷新到 `1.0.22` ### `v1.0.21` Docker Hub 仓库与格式边界校准版本 [#v1021-docker-hub-仓库与格式边界校准版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.21`、Vue2 包 `@flyfish-group/file-viewer@1.0.21`、React 包 `@flyfish-group/file-viewer-react@1.0.21` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.21` 继续保持连续版本 * 清理 `.wps`、`.wpt`、`.et`、`.ett`、`.dps`、`.dpt` 等当前没有开箱即用浏览器渲染方案的 WPS 原生格式说明,避免用户误以为这些格式已经完整支持 * Office 模板和宏格式继续按实际可渲染链路保留,包括 `dot`、`dotx`、`dotm`、`docm`、`xlt`、`xltx`、`xltm`、`pptm`、`potx`、`potm`、`ppsx`、`ppsm` * 新增 Docker Hub 仓库创建脚本,支持用 Docker Hub API 创建 `flyfishdev/file-viewer` 公开仓库,并在异常时输出更明确的安全诊断信息 * 文档站补全文档比对页使用说明,明确 `/compare.html`、`left` / `right` 预置参数、内置示例、URL、本地上传、同步滚动、私有化部署路径和视觉比对边界 * 开源总仓库新增 Gitee 镜像 `gitee.com/flyfish-dev/file-viewer`,GitHub / Gitee 同步交付混淆构建产物、Demo、文档静态产物、示例文件和 tarball * Demo 输出校验继续覆盖 `compare.html`、主入口资源、viewer 资源目录和示例资源,避免上线缺少独立比对入口 * 文档站新增 Cloudflare Pages Direct Upload 脚本和 `docs/public/_headers` 缓存策略,`doc.file-viewer.app` 可切换到 `flyfish-file-viewer-docs.pages.dev` 以改善国内访问速度 * 新增 `options.theme`,支持 `light`、`dark`、`system`;显式主题优先于浏览器 `prefers-color-scheme`,固定浅色业务 UI 可以传 `light` 避免 Markdown、代码、Typst 等预览区域被系统暗色模式带偏 * 新增 `toolbar.position`,支持 `auto`、`top`、`bottom-right`;默认 `auto` 下 PDF 通用下载/打印/HTML 操作栏会悬浮到右下角,避免和 PDF 页码、缩放、目录导航栏形成双顶部导航 * 升级 Vue、Vite、PDF.js、Axios、Marked、React 适配层等第三方依赖到当时 npm latest,并同步刷新 DOCX 构建 chunk * DOCX 渲染关闭生产调试告警,兼容 Word 写入的 `autoSpaceDN` / `autoSpaceDE` 等段落属性,避免控制台被 `DOCX: Unknown document element` warning 刷屏 * README、文档站、React / 纯 JS README、入口缓存策略和 workspace 依赖同步刷新到 `1.0.21` ### `v1.0.20` Typst 直读源文件与边缘部署优化版本 [#v1020-typst-直读源文件与边缘部署优化版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.20`、Vue2 包 `@flyfish-group/file-viewer@1.0.20`、React 包 `@flyfish-group/file-viewer-react@1.0.20` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.20` 统一推进到连续版本 * Typst 严格直读 `.typ` / `.typst` 源文件并以轻量代码视图展示,禁止依赖 sidecar 或预编译 PDF,保证用户上传源码后即可直接查看 * PDF 远端 URL 加载链路新增渐进读取策略: 同源 PDF 默认直接交给 PDF.js 通过 URL 读取,服务端支持 Range 时自动分片加载,避免先整包下载 Blob 后才开始建页;跨域 URL 默认保持旧的兼容下载链路 * 新增 `options.pdf.streaming`、`options.pdf.rangeChunkSize` 和 `options.pdf.withCredentials`,可按业务文件服务能力控制 PDF 渐进读取、Range 分片大小和凭据策略 * 下载按钮支持 URL 源文件回退,流式 PDF 没有预下载 buffer 时也可以触发原始文件下载 * 新增 Cloudflare Pages Direct Upload 部署脚本、`wrangler.toml` 和 `_headers` 缓存策略,便于将 Demo 切到 Cloudflare 边缘网络并保持 `demo.file-viewer.app` 域名不变 * 新增独立文档比对入口 `/compare.html`,支持左右并排预览、示例选择、URL、本地上传和同步滚动,不污染主预览入口 * 新增 Dockerfile、nginx 静态运行配置和 buildx 发布脚本,发布镜像覆盖 `linux/amd64` 与 `linux/arm64`,用于一键部署 Demo 与比对页 * 新增 Office 模板兼容入口,覆盖 `dot`、`dotx`、`dotm`、`docm`、`xlt`、`xltx`、`xltm`、`pptm`、`potx`、`potm`、`ppsx`、`ppsm` ### `v1.0.19` 页面尺寸感知打印与入口组件瘦身版本 [#v1019-页面尺寸感知打印与入口组件瘦身版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.19`、Vue2 包 `@flyfish-group/file-viewer@1.0.19`、React 包 `@flyfish-group/file-viewer-react@1.0.19` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.19` 统一推进到连续版本 * PDF 打印会按真实页面 CSS 尺寸生成完整高保真页图,并通过 `@page size` 固定输出纸张大小,避免导航窗格、视口宽度或缩放状态导致页面被挤压、裁切或只打印当前页 * DOCX / DOC 打印保留白色纸张和文档页尺寸,导出窗口只包含主体页面,避免把 Demo 外壳、工具栏、滚动容器或预览缩放带入打印结果 * 新增 `printStyle` 渲染适配器能力,PDF、DOCX、DOC 等有真实页面尺寸的格式可以按文件自身尺寸输出打印样式,后续格式可复用同一机制 * 将下载、打印、导出 HTML 的实现从 `FileViewer.vue` 抽离到 `useViewerExport` 和导出模板 helper,入口组件回归预览状态、生命周期和操作可用性的单一职责 * 补充打印页尺寸与导出模板单测,并同步刷新文档站、README、Demo 示例版本、开源 release 包和 npm 版本说明到 `1.0.19` ### `v1.0.18` 公开 issue 修复与真实 PDF 示例版本 [#v1018-公开-issue-修复与真实-pdf-示例版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.18`、Vue2 包 `@flyfish-group/file-viewer@1.0.18`、React 包 `@flyfish-group/file-viewer-react@1.0.18` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.18` 统一推进到连续版本 * 修复 GitHub issue #13: PDF 旋转页与导航配置兼容性增强,新增 `options.pdf.navigation` 和 `options.pdf.defaultNavigationVisible`,继续保持页侧边栏 / 树形目录侧边栏切换 * 修复 GitHub issue #9 与 #8: Excel 自动文本色更可靠,支持 workbook drawing 图片渲染,并按渲染链路隐藏不可靠的打印 / 导出入口 * 修复 GitHub issue #4: `.doc` 表格布局和单元格可读性增强,老 Word 文档在白色纸张容器里更接近实际阅读效果 * 修复 GitHub issue #1: `.doc` 的 `msdoc-viewer` CFB 局部 sector 容错改为包管理器无关的 `scripts/patch-msdoc-viewer.mjs`,npm / pnpm / yarn 安装后都可在构建前自动应用 * Demo PDF 替换为项目方提供的 13 页《PDF沉浸式翻译技术说明》,用于验证长文档阅读、缩放、页导航、树形目录、完整打印和 HTML 导出 * 文档站、README、集成说明、示例来源、开源 release 包和 npm 版本说明同步刷新到 `1.0.18` ### `v1.0.17` 打印能力矩阵与完整页打印版本 [#v1017-打印能力矩阵与完整页打印版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.17`、Vue2 包 `@flyfish-group/file-viewer@1.0.17`、React 包 `@flyfish-group/file-viewer-react@1.0.17` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.17` 统一推进到连续版本 * PDF 导航窗格继续完善“页面 / 目录”切换,目录模式支持树形层级、展开折叠和定位跳转,便于用户在长文档中快速预览 * Word、DOC 和 PDF 预览统一增强打印 / HTML 导出,专属导出适配器会移除预览缩放、滚动容器和 Demo 全局布局样式,避免只打印一页或页面被截断 * 新增打印能力动态判断,表格、压缩包、邮件、EPUB、音视频、3D 等不适合直接打印的渲染链路会自动隐藏打印按钮,避免用户进入错误打印流程 * 优化 Demo 暗色模式和 Markdown 阅读面,Markdown / 代码跟随系统主题,PDF / Word / Excel 等原始版式内容保持独立显示;同时替换更丰富的 DOCX / PDF / Markdown 示例并同步压缩包样例 * 新增文档加载、卸载生命周期钩子,以及下载、打印、导出 HTML 的按钮前置校验钩子,历史适配层同步透出事件和操作能力变化 * 文档站、README、集成说明、分发说明和开源 release 包说明同步刷新到 `1.0.17` ### `v1.0.15` 预览交互、打印与集成钩子增强版本 [#v1015-预览交互打印与集成钩子增强版本] * PDF 导航窗格新增“页面 / 目录”切换,目录模式会读取 PDF 大纲并以可展开树形结构跳转,页面模式继续保留页侧边栏 * 增强 Word 和通用文档打印导出,`.docx` / `.doc` 会使用专属导出适配器清理预览缩放、绝对定位和滚动容器,避免只打印一页或页面被截断 * 新增 `options.hooks` 生命周期钩子,覆盖文档开始加载、加载完成、开始卸载和卸载完成,并提供文件类型、文件名、来源、URL、大小、版本和耗时上下文 * 新增 `options.beforeOperation` 与 toolbar 级前置操作钩子,下载、打印、导出 HTML 前都可以返回 `false` 取消,便于接入权限校验、审计确认和业务二次弹窗 * React / 纯 JS 适配层新增 viewer 事件监听入口,基线预览器会向宿主同步生命周期和操作事件 * 文档、README 和四条 npm 包线版本说明同步刷新到 `1.0.15` ### `v1.0.14` 最新发布与文档站同步版本 [#v1014-最新发布与文档站同步版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.14`、Vue2 包 `@flyfish-group/file-viewer@1.0.14`、React 包 `@flyfish-group/file-viewer-react@1.0.14` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.14` 统一抬升到最新版本 * 文档站首页、快速开始、分发说明、支持格式页和 README 中的安装示例同步刷新到 `1.0.14` * 开源总仓库、Demo 静态产物和文档站静态产物重新构建,方便直接下载和验收 * 继续保持 Vue3 / Vue2 / React / 纯 JS 的集成路径、按需异步加载、示例分组和 PDF / OFD / 压缩包 / 邮件 / CAD / 绘图 / 电子书预览链路一致 ### `v1.0.12` 完整格式、分发仓库与 npm 同步版本 [#v1012-完整格式分发仓库与-npm-同步版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.12`、Vue2 包 `@flyfish-group/file-viewer@1.0.12`、React 包 `@flyfish-group/file-viewer-react@1.0.12` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.12` 统一对齐到 npm `latest` * 新增压缩包预览,基于 `libarchive.js` Worker 支持 ZIP、7z、RAR、TAR、GZIP、BZIP2、XZ、CAB、ISO、JAR、APK、CBZ/CBR 等入口,内部文件按需解压、IndexedDB 缓存并继续调用统一预览器 * 新增 EML / MSG 邮件预览,支持头信息、HTML/文本正文、附件下载和附件继续在线预览 * 增强 OLB / DRA 结构预览,基于 `cfb` 解析常见 EDA 复合文档容器,并提供结构树、元件/封装/Padstack 候选、属性、诊断、二进制退化和可读字符串索引 * 预览器新增 `options.watermark`、`options.toolbar` 和 `options.archive`,支持文字/图片水印、下载原文件、完整打印、导出渲染后 HTML、压缩包 worker 和体积限制配置 * 修复 PDF 打印和导出 HTML 的完整性,PDF 会通过专属导出适配器逐页生成全部页面,不再依赖当前滚动视口、当前页或已渲染 canvas,避免只打印当前页或内容被截断 * DWG 入口从单纯提示转换为尽力展示: 误命名 DXF 会直接按 DXF 解析,真实 DWG 会尝试提取内嵌 PNG/JPEG/BMP 预览图,并说明无法完整解析几何的原因 * 新增 Three.js 3D 模型预览器,支持 `glb`、`gltf`、`obj`、`stl`、`ply`、`fbx`、`dae`、`3ds`、`3mf`、`amf`、`usd`、`usda`、`usdc`、`usdz`、`kmz`、`pcd`、`wrl`、`vrml`、`xyz`、`vtk`、`vtp`;`step`、`stp`、`iges`、`igs`、`ifc`、`3dm` 会给出转换原因和建议 * Demo 新增 GLTF / OBJ / STL / PLY / STEP 3D 样例,以及 ZIP、TAR.GZ、EML、MSG、OLB、DRA 样例,支持格式矩阵更新到 135 个扩展名、19 条预览链路 * 文档站全局导航、首页、格式矩阵、分发说明、快速开始和 npm README 均刷新到 `1.0.12` * 开源总仓库已升级为一站式主入口,保留可运行源码、Demo 静态站、文档静态站、样例文件和 release tarball * React / 纯 JS 文档继续推荐 `npm install` 零步骤安装,并补充 pnpm 10 拦截 `postinstall` 时的 `pnpm approve-builds` / `pnpm exec file-viewer-copy-assets` 处理方式 ### `v1.0.9` 媒体、绘图与电子书预览增强版本 [#v109-媒体绘图与电子书预览增强版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.9` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.9` 同步发布到 npm `latest` * 新增 React 包 `@flyfish-group/file-viewer-react@1.0.9` 和纯 JS 包 `@flyfish-group/file-viewer-web@1.0.9`,复用 Vue3 基线资源 * 新增原生 组件 Demo,覆盖 React 组件和纯 JS helper 两种入口,构建后可直接作为私有化静态站点部署 * 增强 PPTX 渲染,补齐组合图形坐标映射、旋转/翻转、主题背景、图片裁剪和 EMF 转 SVG 预览 * 新增 `.epub` 预览,使用 `epubjs` 按需解析 EPUB 包、目录和滚动阅读,并避开部分浏览器超宽分页白板问题 * 新增 `.umd` 电子书预览,按 UMD 文件结构解析元数据、章节目录和 zlib 压缩正文 * 新增 `.mp3`、`.mpeg`、`.wav`、`.ogg`、`.oga`、`.opus`、`.m4a`、`.aac`、`.flac`、`.weba` 音频入口,使用浏览器原生播放器 * 新增 `.excalidraw` 预览,默认使用 rough.js 按需生成只读 SVG,运行环境提供官方 Excalidraw ESM 模块时可优先尝试 `exportToSvg` * 新增 `.drawio` / `.dio` 预览,默认使用随 viewer assets 分发的官方 diagrams.net `GraphViewer` 离线处理 mxGraphModel / mxfile;也可通过 `options.drawing.viewerScriptUrl` 覆盖自托管脚本,异常时回退内置 SVG * 补充 Demo 示例文件、格式矩阵、FAQ 和接入说明 ### `v1.0.8` 文档视觉与预览稳定性版本 [#v108-文档视觉与预览稳定性版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.8` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.8` 同步发布到 npm `latest` * 修复 PDF worker 生命周期,快速切换 PDF / OFD / PDF 时不再触发 worker 销毁告警 * 稳定 OFD 渲染状态,避免反复闪动“正在解析 OFD” * 刷新文档站截图、主题配色和集成示例页视觉 ### `v1.0.7` PDF 自适应修复版本 [#v107-pdf-自适应修复版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.7` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.7` 同步发布到 npm `latest` * 修复 PDF.js 5 下 canvas 布局尺寸被 DPR backing store 干扰的问题,避免 PDF 页面被裁切或显示不完整 * 修复 PDF 默认宽度适配计算,导航窗格开启时也能按当前视口宽度给出可读缩放比例 * 同步刷新线上 Demo、文档说明和开源总仓库产物 ### `v1.0.6` 开源分发版本 [#v106-开源分发版本] * Vue3 包 `@flyfish-group/file-viewer3@1.0.6` 和 Vue2 包 `@flyfish-group/file-viewer@1.0.6` 均已发布到 npm `latest` * 新增 PDF 缩放工具栏、页码状态和可显隐页面导航窗格 * 补齐 OFD、CAD、代码高亮与完整示例文件盒子 * 示例文件选择器支持分组折叠,默认展开第一个分组,并保持同一时间只展开一个分组 * 增加 `pnpm obfuscate` 与 `pnpm release:ecosystem:pack`,库产物支持压缩混淆后分发 * README、文档站和开源总仓库说明同步补充 npm、GitHub、私有聚合仓、优先支持、授权与贡献说明 * npm tarball 只包含 `README.md`、`LICENSE` 和混淆压缩后的 `dist/` ### 文档站与交付说明完善 [#文档站与交付说明完善] * 重写 README 与旧版文档结构 * 增加 Demo 说明、本地开发与打包说明 * 补充截图、接入建议与发布前检查清单 ### `.doc` 渲染能力升级 [#doc-渲染能力升级] * 使用 `msdoc-viewer` 替换旧的 `.doc` 解析方案 * 将 `.doc` 内容渲染在 Word 风格页面容器中 * 增加灰色工作台、白色纸张与页面居中展示效果 ### 示例与工程体验 [#示例与工程体验] * 提供更清晰的本地 Demo 入口说明 * 支持将预览器独立部署并通过静态入口集成 * 本地构建、文档站构建与 npm 打包链路持续收敛 ## 历史版本 [#历史版本] ### `v1.0.3` [#v103] * 修复与优化 PDF 字体、缩放和 Excel 样式相关问题 ### 更早版本 [#更早版本] * 优化 PPTX 加载性能 * 补强 Word 与 Excel 的基础预览能力 * 持续完善 TypeScript 与 Vue 3 版本实现
npm 包版本请以 `package.json` 和实际发布记录为准;本页更偏向说明“这个仓库当前已经演进到了哪里”。
--- # 赞助 File Viewer (/zh/donate) File Viewer 会持续保持 Apache-2.0 开源。赞助主要用于真实文件兼容、文档与示例、离线资产以及项目的长期维护。 ## GitHub Sponsors [#github-sponsors] 可通过 [GitHub Sponsors 赞助 File Viewer](https://github.com/sponsors/wybaby168),支持一次性或持续赞助。该账号属于 File Viewer 主要维护者 [@wybaby168](https://github.com/wybaby168)。 ## 微信与支付宝 [#微信与支付宝] 国内用户可使用 [微信 / 支付宝赞赏页](https://dev.flyfish.group/sponsor?source=github),方便完成一次性支持。 ## 企业技术支持 [#企业技术支持] 赞助用于支持开源维护,除非对应赞助档位有明确说明,否则不包含 SLA 或固定响应时间。私有化部署、定制兼容、商业选型或需要明确交付边界的需求,请使用 [企业技术支持入口](https://dev.flyfish.group/shop)。 无论是否赞助,开源功能、文档和许可都不会受影响。 --- # BPMN 流程图 (/zh/guide/bpmn) 此功能从 3.1.2 起提供。BPMN 需要显式启用,不会增加现有 Full 包的默认依赖。 安装 `@file-viewer/renderer-drawing` 及可选依赖 `bpmn-js@18.28.0`,再向任一标准组件注册: ```ts import { mountViewer } from '@file-viewer/web' import { bpmnRenderer } from '@file-viewer/renderer-drawing/bpmn' mountViewer(document.querySelector('#viewer'), { url: '/documents/process.bpmn', filename: 'process.bpmn', options: { renderers: [bpmnRenderer] } }) ``` 预览支持带 BPMN DI 布局的 BPMN 2.0 XML,可切换流程图与原始源码、平移、缩放、适应视口,也可选择文件中的其他图。源码和流程脚本不会执行。缺少布局或文件损坏时显示诊断,并保留源码查看入口,不擅自生成坐标。 需要默认显示源码或限制输入大小时,可用 `createBpmnRenderer({ initialView: 'source', maxFileBytes: 5 * 1024 * 1024 })`。默认输入上限为 20 MiB。此入口只用于预览,不提供流程编辑和执行。 bpmn.io 上游许可证要求保留其水印;File Viewer 的 Apache-2.0 不会覆盖这份许可证。具体条款见 renderer 包内的 `THIRD_PARTY_NOTICES.md`。 宿主页面有底部悬浮工具条时,在 viewer 容器上设置 `--file-viewer-content-end-inset` 为工具条占用的高度。流程图会预留这部分空间,不改动上游水印。Demo 回归会检查标识和链接没有被工具条遮挡。 Demo 的“BPMN 流程图与源码”使用独立构造、可再分发的样例。用户在 issue 中提供的附件只用于本地验证,不会自动公开到 Demo。 --- # File Viewer CLI (/zh/guide/cli) 零安装运行时使用 `npx file-viewer-cli@latest ...`:这个单 bin 入口严格委托给同版本 `@file-viewer/cli`。项目已经安装 scoped 包后,直接使用本地 `file-viewer` 命令。
创建项目
选择框架、经过验证的运行时版本、格式方案、额外格式、包管理器和资源目录。
接入已有项目
检查 package.json 项目,先展示完整计划,再安装精确版本并接入生成模块。
发布资源
只发布所选能力的资源,同时完整保留原 copy-assets 命令和 Full 包兼容契约。
离线准备
从显式 npm / 私有源并发准备带完整性清单的本地 tgz 目录。
## 从这里开始 [#从这里开始] 运行交互式脚手架: ```bash npm create file-viewer@latest my-viewer # 或 pnpm create file-viewer my-viewer ``` 向导会依次展示框架、方案、File Viewer 发行版、已验证框架版本和可选格式,最后再统一确认。取消或选择不执行时不会修改项目。 需要在 CI 中稳定复现时,把所有选择写明: ```bash npx file-viewer-cli@latest create my-viewer \ --framework vue3 \ --profile standard \ --formats pdf,docx,xlsx,pptx \ --package-manager pnpm \ --non-interactive \ --yes ``` `--yes` 是 `create`、`add`、`install` 的安装和写入确认。非交互模式没有它时只打印计划,不安装依赖,也不写文件。 ## 选择框架和版本 [#选择框架和版本] | CLI 值 | 生成的接入方式 | 版本选择 | | -------------- | ----------------------------------------------- | ----------------------- | | `web` | Vanilla JavaScript + File Viewer Custom Element | 浏览器模板 | | `vue3` | Vue 3 原生组件 | 当前 CLI 目录中的已验证 Vue 3 版本 | | `vue2.7` | Vue 2.7 原生组件 | 已验证 Vue 2.7 版本 | | `vue2.6` | Vue 2.6 原生组件 | 已验证 Vue 2.6 版本 | | `react` | React 18 / 19 组件 | 选择已验证 React 18 或 19 版本 | | `react-legacy` | React 16.8 / 17 兼容组件 | 已验证旧版 React 版本 | | `svelte` | Svelte 原生 action / 组件配置 | 选择已验证 Svelte 3、4 或 5 版本 | | `jquery` | jQuery 插件接入 | 已验证 jQuery 版本 | 交互式向导会列出当前 CLI 目录冻结的精确版本。CI 使用 `--framework-version <精确版本>`。Vite 与框架插件版本作为一套经过构建验证的模板选择,CLI 不会任意拼接未经验证的运行时组合。 ## 选择方案 [#选择方案] | 方案 | 实际含义 | 推荐场景 | | ------------- | --------------------------------------------------------------------------- | -------------------------- | | `standard` | 常用 Word、PDF/OFD、现代 PPTX、Spreadsheet、Archive、Email、Text、Image、Media,并配套精选资源包 | 新项目默认推荐 | | `lite` | 文本、Markdown/代码、图片、音频、视频 | 轻附件预览 | | `office` | 已发布的 Office preset,包含其历史兼容格式 | 需要保持现有 Office preset 契约的项目 | | `engineering` | 已发布的工程 preset | CAD、3D、EDA、Geo 与工程附件 | | `all` | 已发布的 `preset-all` 兼容矩阵 | 已明确使用 `preset-all` 的模块化项目 | | `full` | 对应的历史 `@file-viewer/*-full` 包,加上 CLI 目录中后续新增的全部显式能力 | 能接受安装体积、明确要求全部能力 | | `custom` | 不使用固定 preset,只安装所选格式/能力包 | 严格控制依赖 |
standard 与 Full 是两份不同契约。`standard` 是常用格式默认方案。已经发布的 8 个 `@file-viewer/*-full` 包继续保持原来的 `preset-all`、运行时资源、API 和格式行为,不会被静默替换成 `standard`。直接安装 Full 包也不会自动增加后续专业包;在本 CLI 中选择 `--profile full` 时,会完整保留原 Full 包,再加入目录中后续声明的显式能力。当前新增项包括 DICOM 和数字签名容器,因此 CLI 会在最终确认前醒目展示它们的体积、运行时与许可证边界。
如果安装体积会影响交付,先看 Full 计划: ```bash npx file-viewer-cli plan --framework react --profile full ``` 计划会列出锁定版本、资源命令、重型能力、许可证声明和当前实测 Full 安装区间,不会用一个很小的顶层 tgz 数字掩盖完整依赖闭包。 ## 选择格式与可选能力 [#选择格式与可选能力] 创建或接入时可以直接写文件扩展名或能力 id: ```bash npx file-viewer-cli create viewer \ --framework react \ --profile standard \ --formats dwg,typst \ --yes ``` 先检查目录,再修改已经初始化的项目: ```bash npx file-viewer-cli list npx file-viewer-cli config add dwg --write npx file-viewer-cli config add dicom --write npx file-viewer-cli config add p7m --write npx file-viewer-cli config remove dwg --write npx file-viewer-cli plan npx file-viewer-cli install --yes ``` `standard` 中的重型能力始终需要显式选择。生成模块只 import 固定 profile 与额外能力;运行时仍然只在打开对应格式后才加载 renderer。 所有已选能力都会注册到同一份 File Viewer 生成配置中。DICOM、签名容器、Office、PDF 等格式共用同一个组件、文件入口、生命周期和工具栏;CLI 不会再创建第二套预览页面或按格式分裂业务入口。 ### DICOM 边界 [#dicom-边界] `dicom` 安装可选的本地 DICOM Part 10 renderer,只支持单个本地单帧或多帧文件,包含有界解码和帧切换。它**不提供**多文件序列组装、PACS/DICOMweb、MPR、分割、诊断解读,也不嵌入整套 OHIF 应用。 ### 数字签名能力边界 [#数字签名能力边界] `p7m`(或能力 id `signature`)安装可选的本地签名与证据容器 renderer。它在 Worker 中有界检查 CMS/CAdES、RFC 3161/5544 时间戳、ASiC-S/E、RFC 4998 证据记录、JWS 与公开 OpenPGP 材料。密码学验证结果与证书/密钥信任、合格签名身份、政策合规和法律效力分开呈现。私钥操作、自动解密、远程 `jku`/`x5u` 获取、完整 XAdES 和归档政策验证不在该能力声明内。 ## 创建新项目 [#创建新项目] 脚手架只在确认计划后写入一个小型 Vite 项目和 File Viewer 接入层。按框架不同,会生成: * `package.json`、`index.html`、`src/main.mjs`; * Svelte 所需的 `src/App.svelte` 与 `vite.config.mjs`; * 持久记录选择的 `file-viewer.config.json`; * 默认确定性 renderer 注册模块 `file-viewer.generated.mjs`; * 业务入口中的一条生成模块 import 标记; * 精确版本 File Viewer 依赖和所选静态资源。 只预览、不写入: ```bash npx file-viewer-cli create ./viewer \ --framework svelte \ --framework-version <已验证版本> \ --profile standard \ --non-interactive \ --json ``` 只有审阅 dry-run 后才使用 `--force`。它允许替换冲突的 CLI 脚手架、配置和生成文件,不是任意重写业务文件的通行证。 ## 接入已有项目 [#接入已有项目] 在 `package.json` 所在目录运行 `add`,或者用位置参数传目录: ```bash cd existing-app npx file-viewer-cli add # 在其它目录执行同一操作 npx file-viewer-cli add ./existing-app ``` 检查范围包括: * 优先读取 `packageManager`,然后检查 lockfile; * Vue、React、Svelte、jQuery 依赖及其声明的运行时版本线; * 已安装的 standard / preset / Full File Viewer 方案; * Vite、Vue CLI、Webpack、Next.js、Nuxt 2/3 构建配置; * 可静态证明的 Vite `publicDir`、Nuxt `dir.public` / `dir.static`,以及 Vue CLI、Next.js 的约定静态目录; * 已有 File Viewer 包与当前目录版本是否漂移; * 可以自动加入生成模块 import 的应用入口。 检测到多个框架或多个已安装方案时会停止,要求显式传入 `--framework` 或 `--profile`。动态或禁用的静态目录、多份构建配置、通用 Webpack 输出和未知构建系统会生成明确的 `manualSteps`,并在安装和写文件前失败关闭;确认实际构建目标后可传入受项目边界约束的 `--asset-target` 继续。已有框架版本没有精确命中已验证模板时,CLI 会保留现有运行时并提示风险,不会静默改版本。 先检查检测结果和命令: ```bash npx file-viewer-cli add . --profile standard --json ``` 再应用同一选择: ```bash npx file-viewer-cli add . --profile standard --yes --non-interactive npx file-viewer-cli verify --json ``` 找不到已支持的业务入口时,`add` 会在安装和写入前失败关闭。请显式传入 `--entry <项目内客户端入口>`;不要把浏览器接入代码注入仅用于 SSR 的入口。 ## 配置与生成模块 [#配置与生成模块] 默认 `file-viewer.config.json` 只包含项目相对路径,可以提交到版本库: ```json { "schemaVersion": 1, "framework": "vue3", "profile": "standard", "formats": ["dwg"], "capabilities": [], "assetTarget": "public/file-viewer", "generatedModule": "file-viewer.generated.mjs", "locale": "zh-CN" } ``` | 字段 | 用途 | | -------------------------------- | -------------------------------- | | `framework` / `frameworkVersion` | 原生接入方式和精确的已验证运行时目标 | | `profile` | 固定 preset、兼容 Full 或 custom 选择 | | `formats` / `capabilities` | 通过冻结目录解析的显式增量 | | `assetTarget` | 项目相对静态目录,默认 `public/file-viewer` | | `generatedModule` | 项目相对的确定性注册模块 | | `source` | 显式 registry 或带完整性清单的离线目录 | | `assetBaseUrl` | 显式自托管/CDN 运行时根地址;省略时使用本地同源资源 | | `managedPackages` | CLI 安装并拥有的包,用于安全清理过期重型依赖 | | `locale` | CLI 显示语言;JSON 字段始终使用稳定英文键 | 也可以单独查看或生成模块: ```bash npx file-viewer-cli generate npx file-viewer-cli generate --write ``` 应修改配置后重新生成,不要直接维护生成文件。除非明确使用 `--force`,CLI 不会覆盖用户自有文件。 ### 安装失败恢复边界 [#安装失败恢复边界] 确认执行 create/add/install 后,CLI 会在包管理器步骤前,把已有的项目内 `node_modules` 及 Yarn unplugged 目录原子移动到项目同级、同文件系统的备份区;同时保存 `package.json`、已有 lockfile、Yarn PnP/install-state、CLI 配置/生成模块和受管资产目录。包管理器或资产步骤正常抛错时会恢复这些字节。无法建立安全原子备份区时,CLI 会在调用包管理器前失败关闭。 进程或主机被强制中断不属于正常异常事务,项目同级可能留下 `.<项目名>.file-viewer-install-*`。再次执行前应先检查并恢复该备份,不能直接删除。包管理器 cache(包括项目内 Yarn cache)不会回滚。只有 `managedPackages` 明确记录为 CLI 所有的过期重型依赖才会被移除;未跟踪的依赖声明视为用户所有并保留。 ## 资源命令与 copy-assets 兼容 [#资源命令与-copy-assets-兼容] 已经配置的模块化项目只安装或修复所选资产所有者: ```bash npx file-viewer-cli assets --write ``` 原聚合命令、包名和 bin 完整保留: ```bash npx --no-install file-viewer-copy-assets ./public/file-viewer # 统一 CLI 中的等价入口 npx file-viewer-cli copy-assets ./public/file-viewer ``` 没有项目配置、并传入旧目标/选项时,`file-viewer assets` 也保持旧 copy 行为;存在模块化配置时,它执行所选资产计划,不能把旧参数混进新计划。 | 旧选项 / 环境变量 | 行为 | | ------------------------------- | -------------------------------------- | | `[target-directory]` | 默认 `public/file-viewer` | | `--renderers ` | 只复制指定 renderer 资源组 | | `--no-clean` | 合并模式,也是默认值,保留无关文件 | | `--clean --confirm` | 两个参数同时存在时,才替换专用且安全的 `file-viewer` 目标目录 | | `FILE_VIEWER_PUBLIC_DIR` | 默认输出目录 | | `FILE_VIEWER_SKIP_ASSET_COPY=1` | CI 显式跳过复制 | | `INIT_CWD` | 包管理器调用时的项目根目录 | 复制过程写入 manifest 和 receipt,校验必需文件,拒绝路径越界和符号链接目标,不覆盖无所有者文件或被外部修改的受管资源。现有 Full 包命令继续委托给同版本实现。完整部署 `@file-viewer/web-full/dist/` 已经包含自身资源,不需要再次复制。 ## 私有 registry [#私有-registry] 远程 registry 必须使用 HTTPS;明文 HTTP 只允许显式的 `127.0.0.1` 等回环地址用于本地测试: ```bash npx file-viewer-cli add . \ --profile standard \ --registry https://registry.example.com/ \ --cache-dir .file-viewer/package-cache \ --yes ``` CLI 不会为了获取缺失的 copy-assets 载荷而静默使用环境中的 registry。包含用户名或密码的 registry URL 会被拒绝。认证应放在包管理器的用户/CI 配置中,不要写入项目配置或命令历史。 `--registry` 只影响 npm 包获取。Worker、WASM、字体和 vendor 运行时资源仍然自托管;只有显式设置 `--asset-base-url` 时才会使用经过批准的其它源。 ## 准备离线 tgz 目录 [#准备离线-tgz-目录] `prepare` 及别名 `cache` 会从显式 registry 下载精确的 File Viewer 自有依赖闭包,并发范围为 `1-8`。每个 tarball 都会校验为目录内普通文件,并核对 SHA-512、包名、版本和依赖元数据,最终以原子方式写入目录和 `file-viewer-offline-manifest.json`。完整性只能证明字节与准备清单一致,不能证明 registry 来源可信,因此必须使用受信任的软件源。 先预览: ```bash npx file-viewer-cli prepare \ --framework vue3 \ --profile standard \ --registry https://registry.npmjs.org/ \ --offline-dir .file-viewer/offline ``` 审阅后准备: ```bash npx file-viewer-cli prepare \ --framework vue3 \ --profile standard \ --registry https://registry.npmjs.org/ \ --offline-dir .file-viewer/offline \ --concurrency 4 \ --yes ``` 在目标环境使用经过校验的目录: ```bash npx file-viewer-cli add . \ --profile standard \ --offline-dir .file-viewer/offline \ --cache-dir .file-viewer/package-cache \ --yes \ --non-interactive ``` 离线目录包含所选能力所需的 File Viewer 自有包闭包、必要兼容包,以及供 `create-file-viewer` 使用的精确 `@file-viewer/cli`。它不会顺带镜像无关框架包或业务项目的全部第三方依赖;真正断网安装仍需为这些依赖准备包管理器 cache。npm、pnpm、Yarn Classic 与 Yarn Berry 都会收到各自正确的离线约束;Bun 仍需预热 cache。 安装时 `--registry` 与 `--offline-dir` 互斥。只有根包选择、registry、文件名、版本和完整性哈希全部相同时,已有离线目录才会被复用。 ## 帮助与语言 [#帮助与语言] CLI 会尽量跟随系统语言,也支持显式指定四种帮助语言: ```bash file-viewer --help --lang en file-viewer --help --lang zh-CN file-viewer --help --lang ja-JP file-viewer --help --lang de-DE file-viewer create --help --lang en file-viewer add --help --lang zh-CN file-viewer doctor --help --lang ja-JP ``` 提示和可读计划标签会本地化;`--json` 始终使用稳定英文键,方便 CI 和工具解析。 ### 命令 [#命令] | 命令 | 用途 | 写入门禁 | | --------------------------- | ------------------------------- | ------------------------------ | | `create [dir]` | 创建可构建项目 | 交互确认或 `--yes` | | `add [dir]` | 检测并接入已有项目 | 交互确认或 `--yes` | | `list` | 列出格式、renderer id、包、体积、许可证和资产所有者 | 只读 | | `plan` | 打印精确安装与资产计划 | 只读 | | `init` | 创建/更新项目配置 | `--write` | | `config add/remove ` | 修改显式格式/能力 | `--write` | | `generate` | 生成确定性接入模块 | `--write` | | `install` | 按配置安装精确包和资产 | `--yes` | | `assets` | 安装/修复配置资产;无配置时兼容旧模式 | 配置模式使用 `--write` | | `copy-assets` | 执行完整旧 copy-assets 契约 | 直接写目标;清理还需 `--clean --confirm` | | `prepare` / `cache` | 构建经过校验的本地 tgz 目录 | `--yes` | | `doctor` | 报告依赖、入口、receipt、哈希和资产问题 | 只读 | | `verify` | 执行 doctor,有错误时非零退出 | 只读 | ### 常用选项 [#常用选项] | 选项 | 用途 | | ------------------------------------------ | -------------------------------------------------------------- | | `--project ` | 项目根目录,也支持位置参数 `create/add ` | | `--framework ` | 选择 8 种框架接入之一 | | `--framework-version ` | 选择目录中精确且已验证的运行时模板 | | `--profile ` | `standard`、`lite`、`office`、`engineering`、`all`、`full`、`custom` | | `--formats ` / `--capabilities ` | 增加精确目录项 | | `--package-manager ` | `npm`、`pnpm`、`yarn` 或 `bun` | | `--package-manager-version ` | 精确包管理器版本,用于记录并区分 Yarn Classic 与 Yarn Berry | | `--asset-target ` | 受项目边界约束的相对资源目录 | | `--output ` / `--config ` | 受项目边界约束的生成/配置文件 | | `--registry ` | 显式 npm / 私有源 | | `--offline-dir ` | 带完整性清单的本地 tgz 目录 | | `--cache-dir ` | 可控包管理器 cache/store | | `--concurrency ` | `prepare/cache` 为 `1-8`;安装阶段的包管理器网络/脚本并发为 `1-32` | | `--file-viewer-version ` | 要求与已安装 CLI 目录精确匹配 | | `--asset-base-url ` | 显式批准的运行时资源根地址;默认仍是本地 | | `--json` | 使用稳定英文键的机器可读输出 | | `--non-interactive` | 在 CI 中关闭提示 | | `--yes` / `--write` | 对应命令组的显式执行门禁 | | `--force` | 审阅后替换冲突的 CLI 管理配置/生成/脚手架文件 | | `--dry-run` | 即使同时传入 `--yes` 或 `--write`,所有写命令也强制变为零写入、零安装预览 | ## CI 模式 [#ci-模式] 把计划和修改分开: ```bash # 可审阅,不写入 npx file-viewer-cli plan \ --framework vue3 \ --profile standard \ --formats dwg \ --json > file-viewer-plan.json # 应用精确目录选择 npx file-viewer-cli add . \ --framework vue3 \ --profile standard \ --formats dwg \ --non-interactive \ --yes # 版本、入口 import、receipt、哈希或资产漂移时让 CI 失败 npx file-viewer-cli verify --json ``` JSON 计划保存 command 与 args 数组,而不是经过 shell 插值的字符串,自动化可以先审阅再执行,不需要求值用户可控 shell 文本。 ## 常见问题 [#常见问题] | 提示或现象 | 处理方式 | | ----------------------------- | -------------------------------------------------------- | | `No package.json was found` | 新项目运行 `create`;已有项目在 package.json 目录运行 `add`。 | | 检测到多个框架/方案 | 明确传入目标 `--framework` / `--profile`,CLI 不猜。 | | 请求版本与目录不一致 | 使用匹配的 `@file-viewer/cli@`,不要混用发行目录。 | | 现有框架不是已验证脚手架版本 | 保留并审阅提示,或主动选择已验证 `--framework-version`。 | | 缺少 copy-assets 载荷 | 安装匹配 Full/copy 包、配置显式 registry,或提供经过校验的离线目录。 | | Worker/WASM/字体请求返回 HTML 或 404 | 执行配置资源步骤,按配置根地址提供静态文件,并在正式域名检查 MIME。 | | Full 安装耗时太长 | 优先选 `standard` 或 `custom`;确有 Full 需求时使用私有源/离线 cache 预准备。 | 继续阅读:[模块化方案](/zh/guide/v3-modular-profiles)、[按需 renderer](/zh/guide/on-demand-renderers)、[发布与分发](/zh/guide/distribution)、[格式事实](/zh/guide/formats)。 --- # 方案对比 (/zh/guide/compare) File Viewer 的定位是企业后台、内网和私有化场景里的纯前端文件预览组件。它适合“业务附件快速查看、初筛、检索、打印、导出和自托管交付”,但不替代专业编辑器,也不承诺把所有复杂文件做到像原生软件一样高还原。 ## 免费开源组件与商业版的边界 [#免费开源组件与商业版的边界] 开源 File Viewer 和商业版不是二选一关系。开源版负责浏览器原生、多格式、可离线部署的通用预览;商业版来自 Flyfish Office 自研原生文档引擎,重点替换 Office 文档能力,让同一个 File Viewer 集成获得接近 `file-viewer-pro` 的 Office 预览效果。 | 维度 | 免费 File Viewer 组件 | 商业版 / file-viewer-pro 路线 | | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | 文件格式 | 275 个已注册扩展名(225 个稳定、50 个实验)、47 条预览链路,覆盖 PDF/OFD、Office/iWork、CAD、Typst、压缩包、邮件、电子书、绘图、媒体、3D、数据资产、Adobe 设计文件、可选本地 DICOM、数字签名容器与字节检查;常用能力通过 preset 启用,Adobe 设计、DICOM、签名和二进制检查格式保持显式选择 | 重点增强 Word、Excel、PowerPoint 深水区,可替换 `preset-office` 中的 Word / Spreadsheet / Presentation 能力;PDF、OFD、CAD、Archive 等其它格式继续由开源 renderer 承接 | | 还原度 | 目标是可读、可搜索、可打印、可嵌入业务系统;DOCX 当前偏流式阅读,Excel/PPTX 覆盖常见业务预览,不承诺原生 Office 逐像素一致 | 自研原生文档引擎面向分页、字体、表格、图形、页眉页脚、批注修订和复杂演示布局,适合合同、报告、档案和正式交付预览 | | 性能 | 轻 core + renderer 按需加载,Worker/WASM 懒加载,适合大多数附件中心和在线预览;极端大文件需要结合真实样本做回归 | 针对大文档、大表格和复杂 PPT 做 Worker 解析、分页/分块渲染、虚拟滚动、缓存和内存调优,优先保障主线程流畅 | | 授权与支持 | Apache-2.0 开源,可用于商业项目;社区 issue、打赏和优先支持可协助定位,但上线验收与兼容性风险由项目自行把控 | 商业授权、私有交付、优先技术支持、样本回归和定制兼容路线,适合需要明确责任边界、交付周期和企业支持的场景 | ## 商业版替换 Office 能力的路线 [#商业版替换-office-能力的路线] 商业版交付时提供可插拔的 Office preset / renderer。业务侧保留原来的 Vue、React、Svelte、jQuery、Web Component 或 Vanilla JS 组件入口,也保留主题、水印、工具栏、搜索、事件和其它格式能力,只把 Word、Excel、PowerPoint 的渲染链路切到商业引擎。 ```ts import FileViewer from '@file-viewer/vue3' import engineeringPreset from '@file-viewer/preset-engineering' import { commercialOfficePreset } from './vendor/file-viewer-pro-office' const viewerOptions = { rendererMode: 'replace', preset: [ commercialOfficePreset, engineeringPreset ], theme: 'light' } ``` 实际包名和交付方式以商业授权交付为准。上面的重点是稳定的替换模式:`core`、组件包和非 Office renderer 不变,Office preset / renderer 可被商业版替换。 ## 和服务端转码方案的差异 [#和服务端转码方案的差异] | 方案 | 优点 | 局限 | | ------------------- | ------------------------------------------------- | ----------------------------------------- | | 服务端转码 | 可统一输出 PDF / 图片,便于缓存、归档和权限审计;对复杂 Office 场景更容易做统一兜底 | 需要部署转换服务、队列、临时文件、字体、缓存、重试和清理流程;内网交付成本高 | | Office Online / 云服务 | 效果好,维护少,协作能力成熟 | 内网、私有化、涉密文件、离线环境和严格合规场景不一定适合 | | File Viewer | 纯前端、自托管、按需加载,适合嵌入业务系统和内网附件中心 | 复杂 Office / CAD 仍需要真实文件回归,不替代专业编辑器或最终归档转换 | ## 什么时候优先选 File Viewer [#什么时候优先选-file-viewer] * 文件不适合传到第三方转换服务。 * 项目在内网、私有化、离线或严格 CSP 环境中运行。 * 团队希望用同一个组件覆盖 Office、PDF/OFD、CAD、压缩包、邮件、图片、音视频、代码和结构化数据。 * 业务目标是“预览、初筛、搜索、打印、导出、下载”,而不是在线编辑。 * 前端团队希望按需装配 renderer,而不是在每个页面维护一堆独立 viewer。 ## 什么时候服务端转码更合适 [#什么时候服务端转码更合适] * 需要长期归档,且必须把所有文件统一固化为 PDF 或图片。 * 文件体积很大,浏览器端内存和移动端性能成为主要瓶颈。 * 需要极高还原度、批量转换、OCR、水印固化、合规留痕或异步审核队列。 * 业务已经有稳定的 LibreOffice / OnlyOffice / 商业转换服务,并且运维成本可接受。 ## 推荐组合 [#推荐组合] 很多生产系统可以把两类方案组合起来: * 默认用 File Viewer 做浏览器端即时预览,减少排队和后端转换压力。 * 对少数归档、合同、审计或强一致场景,再触发服务端转 PDF。 * 内网部署时把 Worker、WASM、字体和 vendor 资源随业务静态资源一起自托管。 * 用 issue 和样本回归持续收集真实格式兼容性,而不是只靠合成样例判断效果。 ## 验证清单 [#验证清单] * 在 [Demo](https://demo.file-viewer.app) 试 Word、Excel、PPT、PDF、DWG、ZIP 和 EML。 * 用脱敏业务文件验证你真正关心的格式。 * 检查移动端 WebView、内网静态资源路径、Worker/WASM MIME、CSP 和字体资源。 * 对 Office / CAD 高还原需求,结合 [格式完整度](./format-fidelity) 看清楚边界。 --- # Demo 说明 (/zh/guide/demo) ## 四个验证入口 [#四个验证入口] | 入口 | 地址 | 适合做什么 | | ---------- | -------------------------- | ---------------------------------------------------------------------------- | | 主示例页 | `/` | 切换预置文件、上传本地文件、快速确认各类格式表现 | | iframe 嵌入页 | `/iframe.html` 或 `/iframe` | 无 Demo 外壳的官方嵌入入口,和主 Demo 共用 `?url=`、`from/name` 与 `postMessage(Blob)` 文件传入协议 | | 文档比对页 | `/compare.html` | 左右并排预览两份文档,支持示例、URL、本地上传、交换、重置、同步滚动、聚焦文档浮层搜索和行级定位 | | 组件 Demo | `apps/component-demo` | 同时验证 Vanilla JS / Pure Web、React、Vue3、jQuery、Svelte 和 script 标签接入 | ## 主示例页 [#主示例页] 主示例页采用沉浸式文档工作台。顶部胶囊只保留“打开文件”“粘贴链接”“样例”三个来源操作;当前文件名和真实格式图标悬浮在文档上方,鼠标移入顶部区域时展开,移出 1 秒后以融合动画回到操作栏。右侧搜索、适应、主题、下载和更多操作始终跟随文档能力显示,每个按钮只打开自己的就近浮层,不会让多个操作共用一个失去上下文的弹框。 左下角“最近打开”使用浏览器 `localStorage` 记忆 URL 与样例记录,可逐项移除并随时从历史图标恢复。完整设置收进“更多”,集中展示主题、密度、背景、统一缩放、搜索、打印、导出、水印、压缩包和当前格式专项参数;移动端只保留一个“更多”入口,文档仍在自己的容器内滚动,顶部文件名保持视口居中。 主示例页也内置了完整示例列表,包括 Word、Excel、PPT、PDF、OFD、Typst、XMind、压缩包、邮件、OLB/DRA/GDS/OASIS、CAD、地理数据、3D 模型、Excalidraw、draw\.io、EPUB、UMD、Markdown、代码/文本、图片、音视频、字体/设计资产和结构化数据。示例选择器按文件类型分组展示,每个样例都提供图标、格式名和文件名,点击后会立即打开并自动收起选择器。它适合做三件事: * 快速演示当前项目支持哪些文件类型 * 用本地上传验证 `file` 方案 * 在修改渲染逻辑后做肉眼回归检查 Demo 默认跟随浏览器语言。中文浏览器进入中文样例体系,其他语言进入英文样例体系;推荐用 `?locale=zh-CN` 或 `?locale=en-US` 固定语言,历史 `lang` 参数继续兼容。英文体系包含公开英文 DOCX、PDF、PPTX、XLSX 样例,以及本地英文 Markdown、文本、日志、CSV、JSON、TypeScript、JavaScript、GeoJSON、glTF 和压缩包嵌套样例,运行时不依赖公网 CDN。
File Viewer by Flyfish v2.3.0 中文主 Demo,展示 DOCX、PPTX、DWG、可交互三维 STEP 与文件胶囊融合

动图依次停留在中文 DOCX、NASA PPTX、Autodesk DWG 平面图和可旋转的 STEP 实体,并保留真实的样例库与文件胶囊融合交互。

File Viewer by Flyfish v2.3.0 中文深色样例选择器,按格式分组展示专业文件图标

样例选择器在当前文件附近打开,默认展开当前分组;不同文件类型使用一致的文档轮廓与专属色彩,暗色模式不会对整张图标粗暴套用滤镜。

## Demo 文件传入协议 [#demo-文件传入协议] 官方 Demo 的主入口和 iframe 入口共用同一套文件传入协议。推荐客户系统使用 `/iframe.html`,支持 clean URL 的静态平台也可以写成 `/iframe`;显式传入 `url` 时会进入沉浸式模式,隐藏品牌、最近打开和来源操作,只保留文档与当前格式可用的工具栏。已有系统如果已经接入 `/index.html?from=...&name=...`,仍会继续按同样的 `postMessage(Blob)` 方式工作。 URL 文件: ```html ``` 父页面传二进制: ```html ``` `from` 必须与父页面 origin 一致,Demo 只接受该来源发来的 `Blob`。如果需要兼容旧主 Demo 集成,把上面 iframe 的 `src` 换成 `/file-viewer/index.html?from=...&name=...` 即可,协议不变。正式交付客户时不要只发 `dist/` 散文件,使用 GitHub Release 中的 `file-viewer-v2-*-official-demo-iframe.tar.gz`;包内有 `iframe-example.html`、`README.iframe.md` 和 `iframe-manifest.json`,可直接交给客户部署验收。 ## 文档比对页 [#文档比对页] 文档比对页是独立入口,不会出现在主预览流程里,也不会改变 `FileViewer` 组件本身的默认工具栏。它适合让用户快速核对两份附件的版式差异,例如旧版合同与新版 Word、PDF 与源文档、PPTX 不同版本或 Markdown 与导出物。 直接访问: ```text /compare.html ``` 生产环境体验地址: ```text https://demo.file-viewer.app/compare.html ``` 也可以用查询参数预置左右文件: ```text /compare.html?left=/example/test.doc&right=/example/word.docx ``` 当前支持的查询参数只有两个,文档中不建议额外扩展临时参数,避免和后续组件 API 冲突: | 参数 | 说明 | 示例 | | ------- | ----------------------------------- | -------------------- | | `left` | 左侧面板初始文件 URL,支持同源相对路径或浏览器可访问的绝对 URL | `/example/test.doc` | | `right` | 右侧面板初始文件 URL,支持同源相对路径或浏览器可访问的绝对 URL | `/example/word.docx` | 页面提供三种输入方式,左右两侧互不影响: * 内置示例: DOC、DOCX、PDF、PPTX、Typst、Markdown,可快速演示常见文档差异 * URL 输入: 粘贴业务文件地址后点击预览,适合联调带签名的临时文件链接 * 本地上传: 直接选择本机文件,适合客户现场复现和售前演示 比对页顶部提供“同步滚动”“隐藏 PDF 工具栏”“文字对比”“交换”“重置”和行号定位。同步滚动按两侧真实滚动容器的滚动比例联动,不要求两份文档页数完全一致;搜索采用和主预览一致的轻量浮层交互,先聚焦左侧或右侧文档,再用浏览器常见查找快捷键呼出搜索框,命中只作用于当前聚焦文档,避免两侧同时滚动导致视线丢失。行级定位会复用预览器抽取出的通用锚点,文本类文档通常定位到段落/行块,PDF 会优先使用可用文本层和页面锚点。 “文字对比”不是把两个预览器简单并排。它先通过 `getDocumentTextChunks()` 取得两侧文档锚点文字并消除切片重叠,再使用成熟的 `jsdiff` 做逐行对齐;替换行会继续做字符级 diff,因此中文合同中只改一个数字或词语时,左右两侧会分别标出删除和新增的具体字符。差异视图提供新增、删除、修改、未变化计数、上一处 / 下一处导航,以及“只看差异”过滤。 PDF 在比对页中默认隐藏自身阅读工具栏,只保留正文和可滚动页面,避免左侧 Word / Markdown 与右侧 PDF 因多一条页码缩放栏而错位。需要查看 PDF 页码、缩放、旋转或目录时,可以关闭“隐藏 PDF 工具栏”开关。 为了保持左右对照清晰,比对页默认关闭每个预览器通用操作栏。如果需要下载、打印、导出 HTML、水印或业务权限钩子,请使用主预览入口或在业务侧基于 `FileViewer` 组件自定义比对容器。 私有化部署时,`pnpm build-only` 产物、Docker 镜像和开源总仓库的 `demo/` 目录都会包含同一个入口: ```text demo/compare.html ``` 上线前建议至少验证下面两条: ```bash pnpm verify:demo-output ``` ```text /compare.html?left=/example/test.doc&right=/example/word.docx ``` 当前文字 diff 的稳定主路径是 DOCX、Markdown、代码和纯文本等能够可靠提取阅读顺序的文档。它比较最终可读文字,不解析 Word 内部的修订作者、批注或 OOXML change-tracking 元数据,也不做表格单元格结构 diff。PDF 已可使用同一入口逐步验证,但结果取决于 PDF 文本层的阅读顺序;扫描 PDF 暂不内置 OCR,检测不到文字时会明确提示。多页 PDF 若当前文本层未覆盖全部页面,对比会主动停止而不是把可见页误报成完整结果;完整 PDF 提取、OCR 和版面坐标映射留在后续阶段。需要审计级 PDF OCR 或 Office 修订历史时,仍应在业务侧接入相应服务,并通过 `collectDocumentAnchors()`、`scrollToAnchor()` 和 `getDocumentTextChunks()` 继续关联来源位置。 ## Word 页面效果 [#word-页面效果] ### 问题回归与版本核对 [#问题回归与版本核对] 使用 issue 中相同字节的原始附件验证,不用相似样本代替。当前回归覆盖 XLS 不可见区域搜索、DOC / DOCX 文本修订、DOCX 页相对封面边框,以及桌面和窄屏下的实际上传。独立 Vue CLI / React full 测试项目还会通过真实可调整大小的 Element Plus 抽屉验证冷安装包,不添加源码 alias 或业务侧 Node polyfill。 ```sh # 构建本地 Demo,检查原附件上传、搜索、封面和 HTML 两种视图。 pnpm verify:closed-issue-regressions # 对已构建 Demo 验证 CAD 实际输出像素,以及 XLS 主线程 / Worker 解析。 pnpm verify:issue-245-cad-output pnpm verify:issue-227-cfb pnpm verify:issue-204-resize pnpm verify:mobile-toolbar # 对已构建的候选 tarball 冷安装,再执行实际浏览器回归。 PACKED_ISSUE_PACKAGE_DIR=/absolute/path/to/candidate-tarballs pnpm verify:issue-consumer # 使用已经启动的 Xcode iPhone Simulator,在 Safari 中真实点击。 CLOSED_ISSUE_DEMO_URL=http://127.0.0.1:4179 pnpm verify:issue-243-ios ``` HTML 可直接从样例库选择 `page.html`,切换静态页面与原始源码。DOC / DOCX 使用 `docx.reviewMode: 'all' | 'final' | 'original'` 查看全部文本修订、定稿或修订前原稿;它不会接受或拒绝原文件中的修订,相同文字的未修改副本也不能被标为修订。 样例库提供 `word-revisions.doc` 和 `word-cover.docx`,与 issue 中获准再分发的原附件字节一致。在“更多 → 设置 → 格式 → Word”中切换“DOC / DOCX 文本修订”并应用,即可对比三种模式;文本格式设置中也可以选择 HTML 初始视图,不需要修改业务代码。 `word-native-revisions.doc` 和 `word-native-revisions.docx` 由 Microsoft Word for Mac 开启修订后实际编辑、另存,覆盖公司名称替换、未修改的重复文字、混合粗体、制表符、软换行、段落合并/拆分和表格单元格替换。定稿模式中 `Case join: JOINED` 应在同一段,被删除的软换行不再占一行;原稿模式应恢复原来的两段,并撤销插入的分段。回归样例同时保留 Word“全部接受/全部拒绝”后另存的参考文件和 SHA-256。这些是构造样例,不冒充 #236 未提供的私有原件,也不代表已经覆盖所有格式、批注、移动或表格结构修订。 OFD 样例 `ofd-resource-paths.ofd` 同时使用嵌套文档、替代命名空间前缀和大小写不同的 ZIP 路径。应显示 `Invoice resource reference` 和黑色方块图片。专项测试另外覆盖资源 XML 自身目录、`BaseLoc`、`../`、URI 编码、同名资源优先级及缺失非必需资源。缺少图片或字体目录时保留可读正文;缺少必需页面、损坏 XML 或无效 JBIG2 时必须结束加载并报错,不能空白假成功。样例不等于 #57 尚未提供的原件。 CAD 可选择 `drawing.dxf`、`samples/apache/blocks_and_tables.dwf` 或 `samples/autodesk/house.dwfx`,对比深色背景原色、白纸黑线,再从 CAD 工具栏下载 PNG/JPEG、导出 HTML、打印到 PDF。验收实际输出像素,不只看模式按钮文字。输出的是当前视图 / 当前 DWF 页,需要整图时先点击“适配”。图片下载保留文本或图片水印,并遵守下载/导出权限;水印资源不可读时明确失败,不生成无水印图片。 手机或窄弹窗中的原生组件工具栏保留“搜索、缩放、更多”紧凑入口,搜索框和输出操作按需展开。320px、390px 下控件不得重叠,桌面窄弹窗按自身宽度适配;宽容器保留内联搜索框。iPhone 还要实际输入搜索、关闭键盘并再次翻页,确认整个宿主页面没有停在 Safari 状态栏下方。首屏骨架的 `100vh` 最小高度不能残留在挂载后的应用根节点。 “最近打开”默认收起,点击历史按钮才展开,避免遮挡 sheet 标签。表格回归通过真实鼠标拖动列边界,检查切换 sheet、缩放到 110% 后再次拖拽、恢复缩放后的列宽,并验证关闭“可调整列宽”后拖动不再生效。 MiniFAT 回归使用“未使用但指针无效”的合成旧版 XLS,实际上传后分别经过主线程和 Worker,搜索首行及末行。它不是 #227 的私有原附件,不能代替原文件验收;必需数据流损坏时仍须明确报错,不能静默丢弃单元格。原文件仅需在本地私下验证,不应把敏感内容公开提交。 上线后必须将 `CLOSED_ISSUE_DEMO_URL` 改为 `https://demo.file-viewer.app` 重跑,并核对 `build-info.json` 的源码提交和干净构建标识。iPhone 的“上一页 / 下一页”必须使正文真正移动到目标页,按钮始终可点击;只变化页码不算通过。本地测试成功或 npm 上传成功,都不能证明正式 Demo 已更新。 Word 示例被单独拿出来说明,因为它已经不只是“能打开”,而是具备明确的沉浸式阅读面。`.doc` 和 `.docx` 都会保持页面居中和宽度自适应;DOCX 的页面之外背景可在“沉浸透明 / 格式默认”之间切换,文档本身按主题使用协调的浅色纸张或深色文档面。顶部和右侧工具组固定不动,滚动只发生在文档容器内,因此长文档向上滚动时不会被空白顶栏截断。 ## Vanilla JS / React 组件 Demo [#vanilla-js--react-组件-demo] 仓库中的 `apps/component-demo` 会同时挂载 React 组件、Pure Web controller、`` Custom Element、Vue3 组件、jQuery 组件、Svelte action 和普通 script 标签全局包,用同一份 DOCX 示例验证组件原生挂载、生命周期事件、文件输入和资源加载。调试时运行: ```bash pnpm dev:components ``` 构建上线前运行: ```bash pnpm build:component-demo pnpm --filter @flyfish-group/file-viewer-component-demo preview ``` 如果开发服务和 build preview 中各个面板都能显示同一份 DOCX 示例,就说明 React 组件、纯 JS Custom Element / `mountViewer`、jQuery、Svelte 和 script 标签全局包都可用。 ## 示例文件清单 [#示例文件清单] 仓库中当前提供的示例文件位于 `apps/viewer-demo/public/example/`: 代码、配置和日志类样本已经按真实集成场景扩充,不再只是几行占位内容;它们会覆盖注释、函数、类型、嵌套配置、SQL CTE、Shell 参数、diff 块和长内容滚动,适合验证代码高亮的实际可读性。`word.docx` 使用 Basel Convention 公开中文正式文档,`ppt.pptx` 使用 NASA Science 公开月球科学战略演示稿,`markdown.md` 使用更丰富的长内容样例,`pdf.pdf` 使用项目方提供的 13 页《PDF沉浸式翻译技术说明》,`report.typ` 使用项目内编写的多页 Typst 源文件报告,用于验证浏览器端直接编译、按页 SVG 预览、打印和 HTML 导出链路。DWG 使用 Autodesk 官方 AutoCAD sample files,ODT/ODS/ODP 使用 The Document Foundation 公开 OpenDocument 文件;CAD、3D、绘图、音频和 EPUB 样本使用公开文件或项目内最小夹具,UMD 电子书样本由项目内生成,来源记录在 `apps/viewer-demo/public/example/SOURCES.md`。 | 文件 | 用途 | 对应能力 | | -------------------------------------- | ------------------------------------------------------------------------------- | ------------------- | | `test.doc` | 验证老 Word 文档链路 | `doc` + Word 风格页面容器 | | `word.docx` | Basel Convention 公开中文正式文档,验证现代 Word 长文档、标题层级、表格、图示、主题阅读面和完整打印 | `docx` | | `excel.xlsx` | 验证表格样式链路 | `xlsx` | | `excel.xlsm` | 验证宏工作簿扩展名映射 | `xlsm` | | `excel.xlsb` | 验证二进制工作簿扩展名映射 | `xlsb` | | `excel.xls` | 验证老 Excel 扩展名映射 | `xls` | | `table.csv` | 验证轻量数据表格链路 | `csv` | | `excel.ods` | The Document Foundation 公开 ODS 表格,验证 OpenDocument 表格扩展名映射、真实工作表和样式读取 | `ods` | | `excel.fods` | 标准 Flat ODS XML 夹具,验证平面 OpenDocument 表格扩展名映射 | `fods` | | `excel.numbers` | 验证 Numbers 扩展名映射 | `numbers` | | `sample.rtf` | 验证 RTF 富文本兼容预览 | `rtf` | | `document.odt` | The Document Foundation 公开 ODT 模板,验证 OpenDocument 文本正文抽取和纸张阅读面 | `odt` | | `ppt.pptx` | NASA 公开月球科学战略演示稿,验证星云封面、深色引用页、图文混排、页眉页脚和多页专业版式 | `pptx` | | `slides.odp` | The Document Foundation 公开 ODP 文件,验证 OpenDocument 演示文稿页面结构和文本预览 | `odp` | | `pdf.pdf` | 项目方提供的 13 页真实技术说明 PDF,验证多页阅读、缩放工具栏、页面/目录导航窗格、完整打印和 HTML 导出 | `pdf` | | `ofd.ofd` | 验证 OFD 在线预览 | `ofd` | | `ofd-resource-paths.ofd` | 构造的嵌套路径、XML 命名空间和大小写组合回归,验证正文和图片解析 | `ofd` | | `report.typ` | 验证 Typst 源文件直接读取、浏览器 WASM 编译、按页 SVG 预览、打印和 HTML 导出 | `typ` | | `drawing.dxf` | 使用公开 DXF 样例验证 CAD 图纸预览、平移、缩放、图层和 WebGL/Canvas fallback | `dxf` | | `sample.dwg` | 使用 Autodesk 官方 DWG 样例验证 Worker + LibreDWG WASM 几何解析、块、表格和 CAD 视图适配 | `dwg` | | `samples/apache/blocks_and_tables.dwf` | 使用 Apache Tika 公开 Jira 附件验证原生 DWF 容器、块和表格渲染 | `dwf` | | `samples/autodesk/house.dwfx` | 使用 Autodesk 官方 Viewer 教程样例验证 DWFx/XPS native renderer、多页结构和 CAD 视图适配 | `dwfx` | | `samples/autodesk/robot-arm.dwfx` | 使用 Autodesk 官方 Viewer 教程样例验证 W2D/W3D native renderer 和复杂装配图形 | `dwfx` | | `mindmap.xmind` | 使用项目内生成的双 sheet XMind 夹具验证脑图节点、标签、备注、链接、目录、Panzoom 画布拖拽平移、移动端双指缩放、适配画布、缩放、搜索和导出 | `xmind` | | `map.geojson` | 验证 GeoJSON 点线面离线地图预览 | `geojson` | | `route.kml` | 验证 KML 转 GeoJSON 后预览 | `kml` | | `track.gpx` | 验证 GPX 轨迹转 GeoJSON 后预览 | `gpx` | | `model.gltf` | 使用项目内嵌入数据的最小 glTF 验证 Web 3D 预览 | `gltf` | | `model.obj` | 使用项目内生成的 OBJ 四面体验证 OBJ 几何预览 | `obj` | | `model.stl` | 使用项目内生成的 STL 四面体验证 STL 几何预览 | `stl` | | `model.ply` | 使用项目内生成的 PLY 四面体验证 PLY 几何预览 | `ply` | | `model.step` | 使用 `occt-import-js` 上游基础立方体 STEP 样例验证离线 OCCT Worker/WASM、真实网格、适配视图和统一缩放 | `step` | | `flow.excalidraw` | 使用公开 Excalidraw 图纸验证官方恢复与 SVG 导出预览 | `excalidraw` | | `process.drawio` | 使用官方 draw\.io 示例验证官方 diagrams.net 离线 viewer 与内置 SVG fallback 链路 | `drawio` | | `book.epub` | 使用 Project Gutenberg 公开 EPUB 验证电子书目录和滚动阅读 | `epub` | | `book.umd` | 使用项目内生成的 UMD 电子书验证元数据、目录和 zlib 正文解析 | `umd` | | `archive.zip` | 验证 ZIP 目录读取、按需解压、缓存、内部文档预览和 `archive.entryActions.download` 单条下载按钮策略 | `zip` | | `archive.tar.gz` | 验证 TAR.GZ 压缩包兼容入口、内部文件预览和内部下载按钮隐藏策略 | `gz` | | `sample.eml` | 验证 EML 头信息、HTML/文本正文、附件下载和附件预览 | `eml` | | `sample.msg` | 使用 msgreader 上游公开样例验证 Outlook MSG 解析 | `msg` | | `sample.mbox` | 验证 MBOX 归档识别和首封邮件预览 | `mbox` | | `sample.olb` | 使用项目内生成的 CFB 元件库夹具验证 OLB 结构预览 | `olb` | | `sample.dra` | 使用项目内生成的 CFB 封装图纸夹具验证 DRA 结构预览 | `dra` | | `layout.gds` | 使用项目内生成的 GDSII 版图夹具验证库名、单元、层、边界、路径、文本、引用和 SVG 版图预览 | `gds` | | `layout.oas` / `layout.oasis` | 使用项目内生成的 OASIS 文本结构夹具验证 OAS/OASIS 路由和版图结构退化预览 | `oas` / `oasis` | | `markdown.md` | 验证 Markdown 长内容、表格、代码块和明暗主题阅读面 | `md` | | `notes.markdown` | 验证 Markdown 长扩展名和主题隔离 | `markdown` | | `text.txt` | 验证纯文本展示 | `txt` | | `data.json` | 验证 JSON 高亮 | `json` | | `data.jsonc` | 验证 JSONC 注释配置高亮 | `jsonc` | | `data.json5` | 验证 JSON5 宽松对象语法高亮 | `json5` | | `notebook.ipynb` | 验证 Jupyter Notebook JSON 结构预览 | `ipynb` | | `code.js` | 验证 JavaScript 高亮 | `js` | | `code.mjs` | 验证 ES Module JavaScript 高亮 | `mjs` | | `code.cjs` | 验证 CommonJS JavaScript 高亮 | `cjs` | | `code.ts` | 验证 TypeScript 高亮 | `ts` | | `code.tsx` | 验证 TSX 高亮 | `tsx` | | `code.jsx` | 验证 JSX 高亮 | `jsx` | | `code.css` | 验证 CSS 高亮 | `css` | | `page.html` | 验证 HTML 源码展示,不作为网页执行 | `html` | | `page.htm` | 验证 HTM 源码展示,不作为网页执行 | `htm` | | `data.xml` | 验证 XML 高亮 | `xml` | | `component.vue` | 验证 Vue 单文件组件高亮 | `vue` | | `config.yaml` | 验证 YAML 高亮 | `yaml` | | `config.yml` | 验证 YML 高亮 | `yml` | | `config.toml` | 验证 TOML 配置高亮 | `toml` | | `settings.ini` | 验证 INI 高亮 | `ini` | | `service.proto` | 验证 Protocol Buffers IDL 高亮 | `proto` | | `infrastructure.hcl` | 验证 HCL 基础设施配置展示 | `hcl` | | `formula.tex` | 验证 TeX / LaTeX 源码展示 | `tex` | | `graph.gv` | 验证 Graphviz DOT 源码展示 | `gv` | | `request.http` | 验证 HTTP 请求片段展示 | `http` | | `script.sh` | 验证 Shell 脚本高亮 | `sh` | | `script.bash` | 验证 Bash 脚本高亮 | `bash` | | `query.sql` | 验证 SQL 高亮 | `sql` | | `main.go` | 验证 Go 高亮 | `go` | | `main.rs` | 验证 Rust 高亮 | `rs` | | `code.rb` | 验证 Ruby 高亮 | `rb` | | `code.swift` | 验证 Swift 高亮 | `swift` | | `Main.kt` | 验证 Kotlin 高亮 | `kt` | | `component.react` | 验证 React 片段入口 | `react` | | `index.php` | 验证 PHP 高亮 | `php` | | `main.c` | 验证 C 高亮 | `c` | | `main.cpp` | 验证 C++ 高亮 | `cpp` | | `module.cc` | 验证 C++ 兼容扩展名高亮 | `cc` | | `main.h` | 验证 C/C++ 头文件高亮 | `h` | | `main.hpp` | 验证 C++ 头文件高亮 | `hpp` | | `program.cs` | 验证 C# 高亮 | `cs` | | `change.diff` | 验证 diff 高亮 | `diff` | | `code.java` | 验证 Java 高亮 | `java` | | `code.py` | 验证 Python 高亮 | `py` | | `app.log` | 验证日志文本展示 | `log` | | `pic.png` | 验证 PNG 图片预览 | `png` | | `pic.jpg` | 验证 JPG 图片预览 | `jpg` | | `pic.jpeg` | 验证 JPEG 图片预览 | `jpeg` | | `pic.gif` | 验证 GIF 图片预览 | `gif` | | `pic.bmp` | 验证 BMP 图片预览 | `bmp` | | `pic.tiff` | 验证 TIFF 图片预览 | `tiff` | | `pic.tif` | 验证 TIF 图片预览 | `tif` | | `multipage-ccitt-g4.tif` | 验证两页 CCITT Group 4 TIFF、整组缩放/旋转/适宽、页码状态和大图查看 | `tif` | | `vector.svg` | 验证 SVG 图片预览 | `svg` | | `pic.webp` | 验证 WEBP 图片预览 | `webp` | | `audio.mp3` | 使用 MDN CC0 音频验证 MP3 原生播放 | `mp3` | | `audio.ogg` | 使用 Wikimedia Commons 音频验证 OGG 原生播放 | `ogg` | | `melody.mid` | 验证 MIDI 轨道、时长和音符摘要 | `mid` | | `video.mp4` | 验证视频播放 | `mp4` | | `icon.ico` | 验证 ICO 图标预览 | `ico` | | `sample.sqlite` | 验证 SQLite 表结构和少量数据行预览 | `sqlite` | | `module.wasm` | 验证 WASM 模块导入导出摘要 | `wasm` |
部分兼容格式示例复用了同一份可解析内容来覆盖扩展名入口,例如表格兼容格式和图片兼容格式。Excel 当前使用虚拟表格展示,打印按钮会按能力自动隐藏,避免只打印当前视口。上线前仍建议使用业务真实文件补一轮回归。
## 完整覆盖与绘图说明 [#完整覆盖与绘图说明] 上面的清单已经覆盖当前注册的主要样例扩展名。CAD 链路使用 `@flyfish-dev/cad-viewer` 0.8.1,支持 DWG / DXF / DWF / DWFx / XPS,并增强了 DWG 文字、宽多段线、复杂线型以及外部 SHX 引用识别。0.8.0 底层引擎新增 BOM 提取与 CSV/JSON 导出接口,强化 DWG/DXF 元数据边界,并把 LibreDWG WASM 升级到 0.7.9,修复复杂线型 STYLE 引用为空时合法图纸无法加载的问题;DWG 会按需加载 viewer assets 中 `wasm/cad/` 下的 Worker 和 LibreDWG WASM,DWF/DWFx/XPS 会按需加载 native renderer 与 `dwfv-render.wasm`。 3D 模型示例覆盖 glTF、OBJ、STL、PLY 四条最常用的浏览器模型入口;FBX、DAE、3DS、3MF、AMF、USD/USDZ、KMZ、PCD、VRML/WRL、XYZ、VTK/VTP 等扩展名也已经注册到 `@file-viewer/renderer-3d`。STEP / STP、IGES / IGS 和 BREP 已通过 `@file-viewer/geometry-engine` 在本地 OCCT Worker/WASM 中三角化并交给 Three.js 渲染;`model.step` 会强制验证真实网格、适配视图和统一缩放,不能退回转换提示。官方 Demo 还显式装配实验性的 `@file-viewer/renderer-3d/ifc`,用本地 That Open / Web-IFC Worker、WASM、适配视图、选择和属性面板打开 buildingSMART IFC4、IFC4.3 样例;这不改变默认 preset 或 Full 包。3DM 仍只保留签名识别和专业内核接入说明。二进制检查器样例覆盖全部公开扩展和原始字节、PNG、WASM、ELF、PE、Mach-O、ZIP、Java class 结构,始终只读且不执行文件。XMind 样例用于验证多 sheet 脑图、目录、标签、备注、链接、Panzoom 画布拖拽平移、移动端双指缩放、适配画布、搜索、缩放和导出链路。 Excalidraw 默认使用 `roughjs` 生成只读 SVG,运行环境提供官方 Excalidraw ESM 模块时会优先尝试 `restore` 与 `exportToSvg`;draw\.io / diagrams.net 文件默认使用不执行文档 HTML 的内置 SVG 预览。只有显式设置 `options.drawing.preferOfficial = true` 时才在无 same-origin 权限、带严格 CSP 的 iframe 中加载单独分发的官方 `GraphViewer`;其 styles、shapes、stencils、img、mxgraph 和 math 资源来自本地 `vendor/drawio/`,加载异常会回退内置 SVG。内网路径特殊时可通过 `options.drawing.viewerScriptUrl` 指定同源自托管脚本。 Demo 默认保持 `comfortable` 密度,避免首次打开就进入紧凑版;需要验证效率型外壳、工具栏、压缩包目录、嵌套预览头部、小按钮和搜索输入时,可在 URL 上追加 `?density=compact` 显式切换。压缩包样例用于验证 `libarchive.js` Worker、目录读取、按需解压、IndexedDB 缓存和内部文件继续预览。接入方可以用同一组样例把 `options.archive.entryActions.download` 设为 `false` 或回调,确认内部文件预览栏的下载按钮隐藏,而顶层 viewer 下载原始压缩包的动作仍然可独立控制。邮件样例用于验证 EML / MSG / MBOX 的头信息、正文切换、附件下载和附件预览。地理数据样例用于验证 GeoJSON/KML/GPX 到 MapLibre 矢量叠加层、CRS 归一化和 SVG fallback 的链路;在线 Demo 默认启用 OpenFreeMap 公开底图,私有化或内网接入仍可把 `options.geo.basemap` / `options.geo.tileUrl` 改成离线、自托管或镜像地址。OLB / DRA 样例用于验证 EDA 文件结构树、对象候选、属性、诊断和可读字符串索引;GDS 样例用于验证标准 GDSII 记录解析和 SVG 版图预览;OAS / OASIS 样例用于验证可读 OASIS 文本夹具 SVG 版图与真实二进制 OASIS 的安全结构诊断边界。SQLite、WASM 和 ICO 样例用于验证资产/数据预览链路不会影响普通文档首屏。 ## 公开样例来源 [#公开样例来源] | 示例 | 来源 | 许可 | | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | | `drawing.dxf` | `mozman/ezdxf` 的 `examples_dxf/wipeout_door.dxf` | MIT | | `word.docx` | Basel Convention 的公开中文正式文档 `UNEP-CHW.15-6-Add.5-Rev.1.Chinese.docx` | 公开下载,需保留来源归属 | | `ppt.pptx` | NASA Science 的 `day2-1630-pac-lunarstrategy-noble-nov2023.pptx` 月球科学战略演示稿 | NASA public media usage guidelines, acknowledge NASA and do not imply endorsement | | `sample.dwg` | Autodesk 官方 AutoCAD sample files 的 `blocks_and_tables_-_imperial.dwg` | Autodesk public AutoCAD sample file | | `document.odt` | The Document Foundation Wiki 的 `Book-template-0-2.odt` | CC-BY-SA-3.0 / LGPL-3.0+ / MPL-1.1 | | `excel.ods` | The Document Foundation Wiki 的 `Fixture_Copa_del_Mundo_2014.ods` | CC-BY-SA-3.0 | | `slides.odp` | The Document Foundation Wiki 的 `QA_Impress_Example_01_ODP_File.odp` | CC-BY-SA-3.0 | | `excel.fods` | 项目内编写的标准 Flat ODS XML fixture | Apache-2.0 | | `samples/apache/blocks_and_tables.dwf` | Apache Tika `TIKA-1823` 的 `blocks_and_tables.dwf` Jira 附件 | Apache Software Foundation Jira attachment | | `samples/autodesk/house.dwfx` | Autodesk `viewer-javascript-tutorial` 的 `Sample files/House.dwfx` 官方样例 | MIT | | `samples/autodesk/robot-arm.dwfx` | Autodesk `viewer-javascript-tutorial` 的 `Sample files/RobotArm1.dwfx` 官方样例 | MIT | | `model.gltf` / `model.obj` / `model.stl` / `model.ply` | 项目内生成的最小 3D fixture | Apache-2.0 | | `model.step` | `occt-import-js` 上游 `simple-basic-cube/cube.stp`(上游记录原始来源为 GrabCAD simple-basic-cube) | 保留上游来源归属;仅用于解析回归 | | `buildingSMART-ifc4-building.ifc` / `buildingSMART-ifc43-building.ifc` | `buildingSMART/Certification-datasets` revision `80d976a9b193a26a8e928c3e79bff67af1de68a8` 的公开 Simple Building 样例 | CC-BY-4.0;本地保留许可证、来源 revision 和 SHA-256 台账 | | `binary-*` | 项目内二进制检查器 fixture 与确定性结构生成器 | Apache-2.0;只含非执行性结构字节 | | `mindmap.xmind` | 项目内使用 `@ljheee/xmind-parser` 生成的双 sheet XMind fixture | Apache-2.0 | | `flow.excalidraw` | `neo4j-labs/agent-memory` 的 `poleo-model.excalidraw` | Apache-2.0 | | `process.drawio` | `jgraph/drawio-diagrams` 的 `blog/data-flow.drawio` | Apache-2.0 | | `book.umd` | 项目内生成的最小 UMD 文本电子书 fixture | Apache-2.0 | | `archive.zip` / `archive.tar.gz` | 项目内打包的丰富 PDF、公开 DOCX、Markdown、TypeScript 和 JSON 示例集合 | 随内部文件来源 | | `en/archive.zip` / `en/archive.tar.gz` | 项目内打包的英文 DOCX、PDF、PPTX、XLSX、Markdown、文本、日志、CSV、JSON、代码、GeoJSON 和 glTF 示例集合 | 随内部文件来源 | | `sample.eml` | 项目内生成的标准 MIME 邮件 fixture | Apache-2.0 | | `sample.msg` | `HiraokaHyperTools/msgreader` 的 `test/A memo.msg` | MIT | | `sample.olb` / `sample.dra` / `layout.gds` / `layout.oas` / `layout.oasis` | 项目内生成的 EDA / 版图结构 fixture | Apache-2.0 | | `audio.mp3` | MDN interactive examples 的 `t-rex-roar.mp3` | CC0 | | `audio.ogg` | Wikimedia Commons 的 `Example.ogg` | CC BY-SA 3.0 | | `book.epub` | Project Gutenberg 的 `Alice's Adventures in Wonderland` EPUB | Public domain in the USA | 这些样例的作用是验证预览器兼容性,不承诺覆盖你业务中所有 CAD 图元、绘图插件、UMD 方言或打包器输出。上线前仍建议把自己的高频文件加入回归清单。 ## 建议保留一套自己的回归样本 [#建议保留一套自己的回归样本] 如果你要把这个项目接进正式业务,建议你把下面这几类文件各留一份,形成自己的最小回归集: * 一份版式复杂的 `docx` * 一份历史 `.doc` * 一份带合并单元格和颜色的 `xlsx` * 一份兼容格式表格,比如 `xls` 或 `csv` * 一份业务里最常见的 `pdf` * 一份真实 OFD 发票或归档件 * 一份 DXF 图纸 * 一份 Excalidraw 或 draw\.io 图纸 * 一份 EPUB 或 UMD 电子书 * 一份业务常见压缩包,里面至少包含 PDF、Office 和代码/文本文件 * 一份 EML 或 MSG 邮件,最好带附件 * 一份 OLB、DRA、GDS 或 OASIS,如果业务会接触 EDA / 芯片版图文件 * 一份真实 XMind,如果业务会接触脑图、会议纪要或知识结构文件 * 一份 Markdown 说明文档 * 一份日志或配置文件,比如 `log` / `json` * 一份源码文件,比如 `ts` / `py` / `java` * 一份 `svg` 或 `webp` 图片 * 一份业务常用音频,比如 `mp3` 或 `ogg` 这样每次升级预览器、调整依赖或准备发版时,都能快速知道“这次有没有把关键能力碰坏”。
建议你先用仓库内置样本确认主链路,再用自己的真实文件补一轮回归。前者帮你判断“项目本身能不能跑”,后者帮你判断“它能不能真正接住你的业务”。
--- # 本地开发与打包 (/zh/guide/development) ## 安装依赖 [#安装依赖] ```bash pnpm install ``` ## 常用命令 [#常用命令] | 命令 | 作用 | | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | `pnpm dev` | 启动示例站点 | | `pnpm build` | 类型检查并构建正式示例站点 | | `pnpm build:vue3` | 构建 Vue3 标准组件包产物 | | `pnpm obfuscate` | 对 `packages/components/vue3/dist/` 中的库 JS 产物做压缩混淆 | | `pnpm release:ecosystem:pack` | 构建 core、标准组件包、历史兼容 alias,并生成完整 npm tarball | | `pnpm build:viewer-assets` | 构建 Vue3 基线产物,并同步 Worker/WASM viewer assets 到 `packages/compat/web/viewer` | | `pnpm build:components` | 构建 Vue3 基线 viewer、历史兼容包和所有标准组件包 | | `pnpm verify:demo-output` | 校验 Demo 多入口 HTML 及其引用的静态资源,防止比对页或 hash 资源漏传 | | `pnpm verify:demo-browser-smoke` | 使用 Playwright 打开构建后的主 Demo 和文档比对页,验证轻量样例渲染、双栏组件挂载和比对页快捷键搜索 | | `pnpm verify:browser-smoke` | 构建主 Demo 和 组件 Demo,并统一跑主 Demo、文档比对、React/Web/Vue3/jQuery/Svelte 和 script tag IIFE 浏览器 smoke | | `pnpm verify:branch-roles` | 校验 `origin` 私有 Gitea 聚合仓、main/v2/v3 分支职责、core 公开策略、标准组件包公开仓库和公开仓库策略 | | `pnpm verify:core-api` | 校验 `@file-viewer/core` 根入口、`@file-viewer/core/headless` 契约入口、`@file-viewer/core/browser` 浏览器渲染入口、实例方法、framework-neutral 类型、ESM/声明产物元数据和纯 TS 源码边界 | | `pnpm verify:format-support` | 校验格式目录保持 274 个注册扩展名、224 个稳定、50 个实验、47 条预览链路、无重复扩展名归属,并确认生成表、README / 文档站 / 组件 README 口径一致 | | `pnpm verify:ecosystem-readmes` | 校验根 README / README.zh-CN.md / README.en.md 的公开生态索引、官方文档/Demo、GitHub/Gitee 组件仓库、入口格式、历史兼容包、core 公开仓和格式数量口径 | | `pnpm verify:compatibility-api` | 校验历史兼容包的运行门面边界: React 兼容包转发到标准 React 组件包,纯 Web 兼容包转发到标准 web 组件包,scoped Vue3 根包只保留 core 类型门面、登记过的 alias 和受控公共类型出口,`file-viewer3` 保持薄 alias | | `pnpm verify:compatibility-readmes` | 校验历史兼容包 README / README.en.md 明确推荐迁移到对应 `@file-viewer/*` 标准包名 | | `pnpm verify:wrapper-api` | 校验标准组件包的运行入口、组件/插件/action/helper 导出和 controller 方法,并阻止 `mountViewerFrame`、`postFileToViewer` 等旧独立页面 API 回流,防止不同框架接入体验漂移 | | `pnpm verify:wrapper-options` | 校验标准组件包使用本包本地 controller 暴露统一参数和 handle,controller 只消费 `@file-viewer/core` 底层契约,不重新声明 theme、toolbar、watermark、search、AI、Office、CAD 等预览选项,也不依赖其他组件包 | | `pnpm verify:smoke-matrix` | 校验 `ecosystem/smoke-matrix.json` 覆盖当前 renderer pipeline、标准组件包和真实示例文件 | | `pnpm verify:experience-baseline` | 校验 `ecosystem/experience-baseline.json` 中的 Vue3 当前组件、比对页、历史 React、历史纯 JS 和 script 标签 IIFE 基线体验证据 | | `pnpm verify:ecosystem-tarballs` | 使用 npm dry-run 校验生态包包含中英文 README 和声明入口,且不会打入未声明源码、工作区文件、source map、`.DS_Store` 或非 bin 脚本 | | `pnpm verify:ecosystem-versions` | 校验 core、标准组件包和兼容包版本一致、内部 workspace 依赖范围一致、README 打包声明、标准组件包仓库元数据和历史包依赖边界 | | `pnpm verify:release-status-schema` | 校验开源总仓 `artifacts/release-status.json` 符合 `release-status.schema.json`,并确认 gap 分类摘要结构稳定 | | `pnpm verify:public-main` | 校验开源总仓库的 release manifest、tarball、README、组件仓库索引、入口格式、历史兼容包和源码边界 | | `pnpm verify:production-entrypoints` | 校验完整生态构建后的 package 入口、纯 Web viewer 资源、可导入 ESM 入口,以及 组件 manifest 声明的 ESM、类型、IIFE、viewer assets、复制 CLI 和 Svelte 组件入口 | | `pnpm verify:migration-gates` | 迁移门禁: 类型检查、主 Demo 构建、文档站构建、格式矩阵、根 README 生态索引、smoke 矩阵、分支职责、组件源包、组件运行 API、组件参数面、兼容包 API/README、生态版本和 npm manifest 校验 | | `pnpm deploy:cloudflare` | 构建 Demo、校验多入口产物,并通过 Wrangler Direct Upload 发布到 Cloudflare Pages | | `pnpm docs:deploy:cloudflare` | 构建文档站,并发布到 `flyfish-file-viewer-docs` Cloudflare Pages 项目 | | `pnpm docker:build` | 使用 Dockerfile 构建本机架构镜像 | | `pnpm docker:publish` | 使用 buildx 推送 `linux/amd64` / `linux/arm64` Docker Hub 镜像 | | `pnpm dev:components` | 启动 React + Pure Web + Vue3 + jQuery + Svelte 组件 Demo | | `pnpm build:component-demo` | 构建 组件 Demo,验证上线静态产物 | | `pnpm release:components:pack` | 构建并打包 core、历史兼容包和标准组件包 npm tarball | | `pnpm release:components:publish` | 构建并发布 core、历史兼容包和标准组件包 npm 包 | | `pnpm release:ecosystem:list` | 列出本仓库当前会统一发布的 npm 生态包 | | `pnpm release:ecosystem:pack` | 构建完整生态并生成可离线安装的 npm tarball | | `pnpm release:ecosystem:publish:dry-run` | 对完整生态包执行 npm publish dry-run | | `pnpm release:ecosystem:publish` | 正式发布完整生态包;MFA 账号请使用交互式终端确认 | | `pnpm components:readme` | 根据 `ecosystem/wrapper-readme-template.json`、组件 manifest 和 core 格式定义刷新所有标准组件包中英文 README 与根 README 生态矩阵 | | `pnpm components:verify` | 校验 标准组件包和导出仓库的 README 模板、格式矩阵、仓库元数据、入口、依赖边界和源码边界 | | `pnpm components:publish:dry-run` | 导出并校验独立 组件仓库,发布脚本复跑目标仓库预检后预览 GitHub/Gitee 推送动作 | | `pnpm components:standalone-smoke` | 构建 core 与 标准组件包,导出独立 组件仓库,并用 npm 在临时独立仓库中安装、构建验证 | | `pnpm components:publish` | 导出、校验,并由发布脚本复跑 freshness / 依赖边界预检后提交推送所有独立 组件仓库到 GitHub 和 Gitee | | `pnpm docs:dev` | 启动 Fumadocs + Next.js 文档站 | | `pnpm docs:build` | 构建 Fumadocs + Next.js 静态文档站 | | `pnpm type-check` | 执行 Vue3 基线 TypeScript 类型检查 | | `pnpm type-check:components` | 执行 React / Pure Web / jQuery / Svelte 等标准组件包类型检查 | | `pnpm test` | 运行测试 | ## 推荐验证顺序 [#推荐验证顺序] ```bash pnpm type-check pnpm type-check:components pnpm build pnpm build:vue3 pnpm obfuscate pnpm verify:browser-smoke pnpm verify:demo-browser-smoke pnpm build:component-demo pnpm release:ecosystem:list pnpm verify:branch-roles pnpm verify:core-api pnpm verify:format-support pnpm verify:experience-baseline pnpm verify:ecosystem-versions pnpm components:readme pnpm components:verify --source-only pnpm verify:wrapper-api pnpm components:standalone-smoke pnpm components:publish:dry-run pnpm docker:build pnpm release:ecosystem:pack pnpm verify:production-entrypoints pnpm docs:build pnpm test ``` 如果你要发布 npm 包,再执行: ```bash npm pack ``` 或者直接使用项目内置的发包准备命令: ```bash pnpm release:ecosystem:pack ``` ## 完整生态发版 [#完整生态发版] 当前生态包线都使用 `latest`: | 技术栈 | 分支 | npm 包 | 注册方式 | | --------------- | ------------------------------------ | -------------------------------------------------------------------- | ----------------------------------------------------------- | | 私有原始聚合仓 | `main` | `@flyfish-group/file-viewer-workspace` | 完整 monorepo、apps、docs、core、标准组件包、兼容包、发布自动化和内部集成历史 | | Core | `packages/core` / `file-viewer-core` | `@file-viewer/core` | framework-neutral 预览能力、能力矩阵、事件和操作 API | | Vue3 | `v3` | `@file-viewer/vue3` / `@flyfish-group/file-viewer3` / `file-viewer3` | `createApp(App).use(FileViewer)` | | Vue2.7 | `v2` | `@file-viewer/vue2.7` / `@flyfish-group/file-viewer` | 兼容 Vue2.7 插件式注册 | | Vue2.6 标准组件包 | 当前仓库子工程 | `@file-viewer/vue2.6` | 兼容 Vue2.6 插件式注册 | | React 18 / 19 | 当前仓库子工程 | `@file-viewer/react` / `@flyfish-group/file-viewer-react` | `` | | React 16.8 / 17 | 当前仓库子工程 | `@file-viewer/react-legacy` | legacy React 原生组件 | | Pure Web | 当前仓库子工程 | `@file-viewer/web` / `@flyfish-group/file-viewer-web` | `` / `mountViewer(container, options)` | | jQuery | 当前仓库子工程 | `@file-viewer/jquery` | `$(el).fileViewer(options)` | | Svelte | 当前仓库子工程 | `@file-viewer/svelte` | Svelte component package | 分支职责以 `ecosystem/branch-roles.json` 和仓库根目录 `BRANCHES.md` 为准: 私有 Gitea 的 `main` 是完整原始聚合仓,保留完整 monorepo、统一发布自动化和内部集成历史,不缩减为 core-only,也不等同于 GitHub 开源总仓库。`@file-viewer/core` 的源码通过 `packages/core`、独立公开仓 `flyfish-dev/file-viewer-core` 和开源总仓库分发。标准组件包、core、PPTX 引擎和历史兼容包在当前仓库内作为子工程统一发布;`@file-viewer/ppt@0.3.4` 保持独立 npm 版本和包内许可证,不计入本仓库 88 个 npm 目标,但其公开运行时会作为 `vendor/ppt/` 资产纳入 Demo、Full、copy-assets 与 CDN/IIFE 统一交付。发版前必须通过 `pnpm verify:branch-roles`、`pnpm release:ecosystem:pack` 或 `pnpm release:ecosystem:publish:dry-run`,确保源码边界正确且组件入口使用最新 core 能力。 ## 批量发布与续跑 [#批量发布与续跑] 私有维护仓先构建并冻结一次产物。本地打包默认四路并发(`FILE_VIEWER_PACK_CONCURRENCY`),registry 下载和比对默认四路并发(`FILE_VIEWER_REGISTRY_CONCURRENCY`),均接受 1–8。只有源码和依赖输入未变时才能复用已有构建,不能以跳过构建代替冻结版本验收。 GitHub npm workflow 使用受信任发布,直接上传不可变的 Release tarball。首次写入前校验全部包身份与完整性,再按依赖分层,最多同时进行三次上传和六次 registry 查询。每层必须在 registry 可见且完整性匹配,才开始其依赖包。发生错误后停止调度新工作,并等待已开始的操作结束;重跑同一个 Release 时只跳过字节一致的已发布版本。授权失败或 registry 传播延迟不能成为更换版本号重发的理由。 兼容 alias 的精确依赖变更时,也必须升级自己的版本。尤其不能复用旧 `msdoc-viewer`,否则这部分用户仍会加载旧 DOC 解析器;版本冻结检查会拒绝这种计划。发布后仍需完成 registry 校验、冷安装、生产 Demo 验证和标准 postcheck。 ## 主要产物位置 [#主要产物位置] * 正式 Demo 构建产物: `apps/viewer-demo/dist/` * Docker 镜像运行产物: `apps/viewer-demo/dist/` 会被复制到 nginx 的 `/usr/share/nginx/html/` * Vue3 标准组件包产物: `packages/components/vue3/dist/` * 文档站构建产物: `apps/docs-site/out/` * npm 包 tarball: 仓库根目录下的 `*.tgz`,完整生态 tarball 默认位于 `.release/ecosystem/`,组件离线安装包位于 `.release/components/` * Pure Web 随包 viewer assets: `packages/compat/web/viewer/` * 组件 Demo 构建产物: `apps/component-demo/dist/` * 公开 GitHub / Gitee 仓库: 提供 core、标准组件包、兼容包、Demo、文档源码,同时保留混淆压缩后的库产物、Demo 静态站点、文档静态站点、示例文件和 tarball ## 发版前检查清单 [#发版前检查清单] * README 是否和当前代码能力一致 * README 和文档站是否同时写清 Vue3 / Vue2.7 / Vue2.6 / React / React Legacy / Pure Web / jQuery / Svelte / Core / PPTX 包名、版本和接入方式 * 文档站中的支持格式、native component package 接入说明和 Demo 截图是否最新 * `file` / `url` 的行为说明是否与运行逻辑一致 * 每轮迁移是否已经运行 `pnpm verify:migration-gates`,覆盖类型检查、主 Demo 构建、文档站构建、格式矩阵、根 README 生态索引、smoke 矩阵、体验基线证据、分支职责/源码边界、core API 与纯 TS 边界、组件源包校验、组件运行 API 与参数面一致性、兼容包运行/类型门面、兼容包 README 迁移提示、生态版本/依赖一致性和 npm manifest 列表校验 * 生态目标、包名、仓库和分支职责是否已经通过 `pnpm verify:ecosystem-readmes` / `pnpm verify:branch-roles`,确认 `ecosystem/wrappers.json` / `ecosystem/branch-roles.json` / core 格式矩阵口径一致 * 新增格式、示例或标准组件包时,`ecosystem/smoke-matrix.json` 是否已经同步补充对应样本、surface 和断言项 * 修改主入口、文档比对、历史 React / 纯 JS 组件或 script tag 接入时,`ecosystem/experience-baseline.json` 是否同步补充对应页面、特性组、事件/按钮/打印导出/视觉证据和验证脚本 * 每个标准组件包是否仍由 `wrapperCoverage.requiredFamilies` 覆盖 PDF、DOCX、XLSX、图片、Markdown、CAD、压缩包、邮件和地理数据这些关键族 * 生态 npm 版本、内部 workspace 依赖和仓库元数据是否已经通过 `pnpm verify:ecosystem-versions`,确认 core、标准组件包和历史兼容包不会漂移,且标准组件包仍指向对应 GitHub 公开仓库 * 根 README 与开源总仓库 README 是否已经通过 `pnpm verify:ecosystem-readmes` / `pnpm verify:public-main`,确认组件入口格式、GitHub/Gitee 仓库和历史兼容包口径没有漂移 * 生态 npm tarball 是否已经通过 `pnpm verify:ecosystem-tarballs` 或正式 pack 后的自动校验,确认每个包都包含中英文 README,并避免未声明源码、工作区目录、source map、构建配置和本地元数据泄露 * npm 最新版安装链路是否已经通过 `pnpm verify:npm-install-smoke`,确认 registry 安装和本地 tgz 依赖闭包安装在 npm 11.17.0 下都能正常完成并导入 * 生产入口是否已经通过 `pnpm verify:production-entrypoints`,确认 core、PPTX、Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 和历史兼容包的声明入口存在且 ESM 入口可被真实导入,并确认组件 manifest 的 ESM、类型、IIFE、viewer assets、复制 CLI 和 Svelte 组件入口与 package 字段、实际文件一致 * 本地构建和文档构建是否全部通过 * 主 Demo、文档比对页和 组件 Demo 是否已经通过 `pnpm verify:browser-smoke`,确认轻量文档实际渲染、左右比对组件挂载、`Ctrl/Command+F` 搜索浮层、React/Web/Vue3/jQuery/Svelte standard component package 和 script tag IIFE 行为正常 * React / Pure Web / jQuery / Svelte 组件 Demo 是否在开发服务和 build preview 中都能显示内容 * `packages/compat/web` / `packages/components/web` 的资源复制结果是否已经由最新构建产物同步 * `file-viewer-copy-assets` 是否生成 `flyfish-viewer-assets.json`,且 archive / CAD 等 worker/WASM 资源校验为 `valid: true` * `.release/component-repos/*` 是否已经通过 `pnpm components:publish:dry-run` 预检,确认 GitHub/Gitee remotes、README、manifest、source HEAD freshness、依赖边界和 npm 入口元数据均来自 `ecosystem/wrappers.json` * 组件 README 是否已经通过 `pnpm components:readme` 和 `pnpm components:verify --source-only`,确认中英文模板、生态矩阵、格式矩阵、官方文档和 Demo 链接与 `ecosystem/wrapper-readme-template.json` 一致 * 根 README 是否已经通过 `pnpm verify:ecosystem-readmes`,确认公开仓库同步前已包含 core 公开仓、标准包、历史兼容包、GitHub/Gitee 组件仓库、官方文档/Demo、私有聚合仓与优先支持说明 * 独立 组件仓库是否已经通过 `pnpm components:standalone-smoke`,确认离开 monorepo 后可用 npm 安装本地生态 tarball 并完成构建 * `npm pack` 产物中是否包含正确的 `dist/` 和 README * 生态 tarball 是否包含 core、标准组件包、历史兼容包、README 中英文说明和必要的 `viewer/` / `dist/` 文件,且不包含 `.DS_Store`、source map 或私有源码 * 开源总仓库是否在 `pnpm release:public` 后自动通过 `pnpm verify:public-main`,确认 `artifacts/release-manifest.json`、`artifacts/release-status.json`、`artifacts/release-status.schema.json`、tarball、README 和 组件仓库索引均与当前生态清单一致 * 混淆后的 `packages/components/vue3/dist/index.mjs` 是否仍可被业务项目正常导入 * README 是否包含官方文档、在线 Demo、完整 npm 生态、私有化部署、GitHub / Gitee 公开仓库、私有聚合仓与优先支持和 Apache-2.0 许可证说明 ## 部署建议 [#部署建议] 项目可以部署在 Cloudflare Pages、Vercel 或任意静态资源服务上。对外提供 Demo 和文档站时,建议: * 使用 `file-viewer.app` 承载官方组件门户,负责产品定位、资源导航、生态入口和商业支持入口 * 使用稳定域名承载官网 Demo,方便用户快速验证能力 * 性能敏感场景优先使用 Cloudflare Pages / CDN 边缘节点承载官网、Demo 和文档静态产物,并保持 `file-viewer.app`、`demo.file-viewer.app`、`doc.file-viewer.app` 作为产品主入口 * 官方门户 Cloudflare Pages Direct Upload 可执行 `pnpm site:deploy:cloudflare`,默认发布到 `flyfish-file-viewer-site` * Cloudflare Pages Direct Upload 可执行 `CLOUDFLARE_PAGES_PROJECT=flyfish-file-viewer pnpm deploy:cloudflare`,项目名可按控制台实际项目覆盖 * 文档站 Cloudflare Pages Direct Upload 可执行 `pnpm docs:deploy:cloudflare`,默认发布到 `flyfish-file-viewer-docs` * 首次切换到 Cloudflare Pages 时,需先在 Pages 项目中添加 `demo.file-viewer.app` 自定义域名;如果 `flyfish.dev` 的 DNS 不在当前 Cloudflare 账号,需要在 DNS 托管处把 `demo.file-viewer.app` 的 CNAME 指向 `flyfish-file-viewer.pages.dev` * 文档站切到 Cloudflare Pages 时同理,需要把 `doc.file-viewer.app` 添加到 `flyfish-file-viewer-docs` 的自定义域名,并让 DNS CNAME 指向 `flyfish-file-viewer-docs.pages.dev` * `apps/viewer-demo/public/_headers` 已为哈希资源、WASM/Worker、示例文件和 HTML 配置缓存策略,部署到 Cloudflare 后会自动生效 * `docs/public/_headers` 已为 Next.js 哈希资源、图片、原始 Markdown 入口和 HTML 配置缓存策略,部署到 Cloudflare 后会自动生效 * Vanilla JS / Pure Web、React、jQuery 和 Svelte 包默认在用户项目内原生挂载预览器;如需 Worker/WASM 自托管,请使用资源复制命令并配置对应 options * Docker 镜像发布后可直接运行 `flyfishdev/file-viewer:latest`,主预览入口是 `/`,零依赖嵌入入口是 `/iframe.html`,文档比对入口是 `/compare.html` * 不要把已移除的旧式页面协议写成推荐接入方式 * 发布前先用本地构建产物做一次完整 smoke test ## 开源总仓库与支持 [#开源总仓库与支持] 开源总仓库用于分发可直接运行的主 Demo 源码、core、标准组件包、兼容包、文档源码、构建产物、示例和 release tarball。私有 Gitea 继续作为完整聚合仓,保留统一发布自动化和内部集成历史。需要支持开源维护时,可使用 [GitHub Sponsors](https://github.com/sponsors/wybaby168) 或 [微信 / 支付宝](https://dev.flyfish.group/sponsor?source=github);需要私有化、定制或明确响应时间时,请使用 [企业技术支持](https://dev.flyfish.group/shop)。 二开或商用时,请保留 File Viewer by Flyfish / `@flyfish-group/file-viewer3` 或 `@flyfish-group/file-viewer` 的来源说明、许可证和版权信息。通用问题修复和通用增强建议通过 issue / PR 贡献回来。 --- # 发布与开源分发 (/zh/guide/distribution) ## 分发渠道 [#分发渠道] | 渠道 | 地址 | 内容 | | ------------------ | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | 官方网站 | [file-viewer.app](https://file-viewer.app) | 一站式组件门户、产品定位、应用场景、资源导航和商业支持入口 | | 官方文档/组件主页 | [doc.file-viewer.app](https://doc.file-viewer.app) | 主文档域名,提供组件主页、接入文档、格式说明和开源分发说明 | | 在线 Demo | [demo.file-viewer.app](https://demo.file-viewer.app) | 可直接体验完整预览器,用于快速验证能力 | | 文档比对 Demo | [demo.file-viewer.app/compare.html](https://demo.file-viewer.app/compare.html) | 独立入口,支持左右并排预览、上传、URL、同步滚动、聚焦搜索,以及 jsdiff 逐行对齐和字符级文字差异 | | 官方 iframe Demo 交付包 | GitHub Release: `file-viewer-v2-*-official-demo-iframe.tar.gz` | 官方 Demo 的零依赖构建产物,包含 `iframe.html`、兼容原主 Demo 的 `index.html`、父页面示例、说明文件、样例和离线 Worker/WASM/vendor 资源 | | Docker 镜像发布目标 | `flyfishdev/file-viewer:latest` | 可一键部署的 nginx 静态镜像,发布时支持 `linux/amd64` 和 `linux/arm64` | | npm 标准生态 | [生态组件总览](/zh/guide/ecosystem) | 本仓库 54 个发布目标:`@file-viewer/core`、独立 renderer、preset、`@file-viewer/pptx` 引擎、Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 和历史兼容包;独立版本的 renderer 依赖不计入 npm 目标数 | | 自托管静态资源 | `file-viewer/assets/*`、`file-viewer/vendor/*`、`file-viewer/wasm/*` | Worker、WASM、示例文件和重型渲染器资源,按需自托管 | | GitHub 开源总仓库 | [github.com/flyfish-dev/file-viewer](https://github.com/flyfish-dev/file-viewer) | 一站式入口: README、LICENSE、主 Demo 源码、core、标准组件包、兼容包、文档源码、构建产物、示例和 release tarball | | Gitee 开源总仓库 | [gitee.com/flyfish-dev/file-viewer](https://gitee.com/flyfish-dev/file-viewer) | 国内镜像目标,使用干净历史控制仓库体积;如远端配额阻塞,以 GitHub 开源总仓库和 release 为准 | | GitHub Sponsors | [github.com/sponsors/wybaby168](https://github.com/sponsors/wybaby168) | 一次性或持续赞助开源维护 | | 微信 / 支付宝赞赏 | [dev.flyfish.group/sponsor?source=github](https://dev.flyfish.group/sponsor?source=github) | 国内用户便捷的一次性支持入口 | | 企业技术支持 | [dev.flyfish.group/shop](https://dev.flyfish.group/shop) | 私有化、定制兼容、聚合交付和需要明确响应时间的需求 | ## npm 安装 [#npm-安装] 新项目优先使用 `@file-viewer/*` 标准包名。历史 `@flyfish-group/*` 包继续同步发布,但主要用于旧项目平滑升级。 | 场景 | 标准包 | 历史兼容包 | | --------------------------------- | ------------------------------------ | -------------------------------------------- | | Core 底座 | `@file-viewer/core` | 无 | | 二进制 PPT 运行时 | `@file-viewer/ppt@0.3.4` | 独立版本 npm 依赖;公开资产纳入 Demo/Full/CDN 交付 | | PPTX 原生引擎 | `@file-viewer/pptx` | 无 | | Word renderer | `@file-viewer/renderer-word` | 无 | | 演示文稿 renderer | `@file-viewer/renderer-presentation` | 无 | | 绘图 renderer | `@file-viewer/renderer-drawing` | 无 | | 3D 模型 renderer | `@file-viewer/renderer-3d` | 无 | | 数据资产 renderer | `@file-viewer/renderer-data` | 无 | | EDA renderer | `@file-viewer/renderer-eda` | 无 | | 轻量 renderer preset | `@file-viewer/preset-lite` | 无 | | Office renderer preset | `@file-viewer/preset-office` | 无 | | 工程 renderer preset | `@file-viewer/preset-engineering` | 无 | | 全量 renderer preset | `@file-viewer/preset-all` | 无 | | Vite 按需装配插件 | `@file-viewer/vite-plugin` | 无 | | Vanilla JS / Pure Web / script 标签 | `@file-viewer/web` | `@flyfish-group/file-viewer-web` | | Vue3 | `@file-viewer/vue3` | `@flyfish-group/file-viewer3`、`file-viewer3` | | Vue2.7 | `@file-viewer/vue2.7` | `@flyfish-group/file-viewer` | | Vue2.6 | `@file-viewer/vue2.6` | 无 | | React 18/19 | `@file-viewer/react` | `@flyfish-group/file-viewer-react` | | React 16.8/17 | `@file-viewer/react-legacy` | 无 | | jQuery | `@file-viewer/jquery` | 无 | | Svelte | `@file-viewer/svelte` | 无 | 所有生态还提供对应的 `*-full` 包:`web-full`、`vue3-full`、`vue2.7-full`、`vue2.6-full`、`react-full`、`react-legacy-full`、`jquery-full`、`svelte-full`。full 包已内置 `preset-all` 和版本对齐的 renderer/Worker/WASM/字体/vendor 资产,不要重复安装 preset;Vite 或随包 CLI 会把包内资产发布到 `<部署基址>/file-viewer/`,其中包括 `vendor/ppt/` 下完整的二进制 PPT 0.3.4 公开运行时。 常用安装命令: ```bash pnpm add @file-viewer/vue3 @file-viewer/preset-office # 重度用户 / 全格式附件中心: pnpm add @file-viewer/vue3-full # 非 Vite 或特定生态也可把 @file-viewer/vue3 替换为 @file-viewer/web / react / vue2.7 / vue2.6 / jquery / svelte。 ``` Webpack、Rspack、Rollup、Umi、传统多页应用和内部组件库通过 `options.preset` 显式注入 preset。Vite 项目可以额外安装插件并使用免配置自动装配: ```bash pnpm add -D @file-viewer/vite-plugin ``` ```ts fileViewerRenderers({ copyAssets: true }) ``` 插件会自动发现已安装的 full / `@file-viewer/preset-*`,注入能力,并在 full 场景把完整 Worker、WASM、字体和 vendor 资源发布到 `<部署基址>/file-viewer/`;需要极致裁剪时再用单 renderer + `formats`。 常用定制边界: | 配置 | 说明 | | ------------------------------------ | ---------------------------------------------------------------------------------------- | | `copyAssets:true` | 识别 full / preset;full 在开发与生产构建中发布到 `<部署基址>/file-viewer/`,标准包/preset 保持原有根目录行为;full 包必须开启 | | `formats` / `renderers` | 不使用 preset、或在 preset 外补充少数格式时,生成精确 renderer import | | `scan:true` | 扫描源码中的 `fileViewerFormats`、`data-file-viewer-formats`、上传 `accept` 等格式 hint | | `preset:'auto'` / `autoPresets:true` | 开启 `scan:true` 时继续保留已安装 preset 的自动激活 | | `inject:false` | 关闭自动注入,改为手动导入 `virtual:file-viewer-renderers` 并传入 `options.renderers` | Vanilla JS / Pure Web: ```html ``` Vue3: ```ts import { createApp } from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue3' createApp(App).use(FileViewer).mount('#app') ``` Vue2.7: ```ts import Vue from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue2.7' Vue.use(FileViewer) new Vue({ render: h => h(App) }).$mount('#app') ``` React: ```tsx import FileViewer from '@file-viewer/react' export function Preview() { return (
) } ``` Svelte、jQuery、React Legacy、Vue2.6、Core 自定义接入和 script 标签示例见 [生态组件总览](/zh/guide/ecosystem)。标准包只在其所选 renderer 需要静态资源时发布对应资产;full 包要保证完整格式支持,必须使用 Vite `copyAssets:true`,或运行随包安装的同版本 CLI:`npx --no-install file-viewer-copy-assets ./public/file-viewer`。复制脚本会写入 `flyfish-viewer-assets.json`,并按 core renderer asset manifest 校验 Archive、CAD、DOCX、Spreadsheet、Typst、SQLite、PDF 等 Worker/WASM/字体/vendor 资源。`web-full` 也可直接部署已含资源的完整 `dist/`。 ## Release Tarball 安装 [#release-tarball-安装] 如果你在内网、离线环境,或者 npm 发布权限还没有完成配置,也可以直接使用开源总仓库 `artifacts/` 里的 release tarball: ```bash npm install ./artifacts/flyfish-group-file-viewer3-*.tgz npm install ./artifacts/file-viewer-core-*.tgz npm install ./artifacts/file-viewer-vue3-*.tgz npm install ./artifacts/file-viewer-vue2.7-*.tgz npm install ./artifacts/file-viewer-vue2.6-*.tgz npm install ./artifacts/file-viewer-react-*.tgz npm install ./artifacts/file-viewer-react-legacy-*.tgz npm install ./artifacts/file-viewer-web-*.tgz npm install ./artifacts/file-viewer-jquery-*.tgz npm install ./artifacts/file-viewer-svelte-*.tgz npm install ./artifacts/file-viewer-renderer-word-*.tgz npm install ./artifacts/file-viewer-renderer-presentation-*.tgz npm install ./artifacts/file-viewer-preset-all-*.tgz npm install ./artifacts/file-viewer-pptx-*.tgz npm install ./artifacts/flyfish-group-file-viewer-*.tgz npm install ./artifacts/flyfish-group-file-viewer-web-*.tgz npm install ./artifacts/flyfish-group-file-viewer-react-*.tgz ``` Core、独立 renderer、preset、PPTX 原生引擎、Vanilla JS / Pure Web、Vue3、Vue2.7、Vue2.6、React、React Legacy、jQuery、Svelte 和历史兼容 tarball 都会随开源总仓库一起生成。`@file-viewer/ppt@0.3.4` 是独立版本的 npm 运行时依赖,不计入 54 个 File Viewer npm 发布目标;普通 ESM/Vite 由包管理器直接解析,Demo、Full、copy-assets 与 CDN/IIFE 则在 `vendor/ppt/` 交付同一套经过清单与 SHA-256 校验的公开运行时。默认无需配置 URL;`pptModuleUrl`、`pptWorkerUrl`、`pptWasmUrl` 与 `pptFontUrl` 仅用于自定义资源路径。`file-viewer3` 非 scoped 兼容包仍会同步发布到 npm,但它和 `@flyfish-group/file-viewer3` 包体重复,开源总仓库下载区只保留 `flyfish-group-file-viewer3-*.tgz` 这一份 Vue3 兼容 tarball。React tarball 依赖 web viewer 包,离线安装时请按 npm 依赖关系一起放入本地源或依次安装。 完整 full 部署会从包内自托管 viewer assets。每个 full 包安装的同版本 `npx --no-install file-viewer-copy-assets ./public/file-viewer` 会发布 PDF.js worker/CMap/WASM/standard fonts、二进制 PPT 0.3.4、PPTX Worker、CAD WASM、Typst WASM/默认字体、SQLite WASM、压缩包 worker 和其它资产,并生成 `flyfish-viewer-assets.json` 供验收。`web-full` 可直接部署完整 `dist/`,无需为二进制 `.ppt` 额外配置运行时 URL。 所有 full 包的默认静态目录都是部署基址下的 `file-viewer/`(根部署即 `/file-viewer/`),会自动指向该目录下的 PDF.js、DOCX、二进制 PPT、PPTX、Excel、CAD、Typst、Draw\.io、SQLite 和 Archive 资源。资源放在其它位置时,启动前调用 `setDefaultFullAssetBaseUrl('/your-prefix/')`;显式 `options.*Url` 仍保持最高优先级。直接使用 CDN `web-full`,或完整部署它的整个 `dist/` 目录时,包括 `vendor/ppt/` 在内的包内资源都会按脚本 URL 自动解析。 ## 官方 Demo iframe 交付包 [#官方-demo-iframe-交付包] 客户需要“直接拿官方 Demo 构建产物做 iframe 集成”时,使用 GitHub Release 中的 `file-viewer-v2-*-official-demo-iframe.tar.gz`。这个包不要求业务项目安装 npm 包,解压后把所有文件发布到同一个静态目录即可,目录中的 `assets/`、`vendor/`、`wasm/` 和 `example/` 必须保持相对位置不变。 `/iframe.html` 是推荐的无 Demo 外壳入口,支持 clean URL 的静态平台也可以写成 `/iframe`;`/index.html` 保留原主 Demo 能力,并兼容同一套 `url`、`from`、`name` 和 `postMessage(Blob)` 协议。 URL 文件嵌入: ```html ``` 父页面拿到二进制后再传入 iframe: ```html ``` `from` 必须等于父页面 origin,Demo 只接受该 origin 发来的 `Blob`。包内的 `iframe-example.html` 同时覆盖 URL 与本地文件 `postMessage` 两条路径;发布前由 `pnpm release:demo-iframe:pack` 和 `pnpm verify:demo-iframe-artifact` 生成并校验,随后进入 `release:standard:build`、`release:public` 和 GitHub Release 附件校验链路。 部署到 Cloudflare Pages 时,平台会根据访客 `Accept-Encoding` 自动启用边缘压缩。项目的 `scripts/deploy-cloudflare-pages.mjs` 还会在 Direct Upload 前对超过 Pages 单文件限制的 WASM 做 Brotli 预压缩,并在 `_headers` 中写入 `Content-Encoding: br`、`Vary: Accept-Encoding`、`Content-Type: application/wasm` 和长期缓存策略,确保 27MB 级 Typst compiler WASM 仍然通过原始 `.wasm` URL 稳定加载。上线后运行下面的命令确认官网、文档站、Demo 和 Typst WASM 都已经走 Cloudflare 压缩: ```bash pnpm verify:cloudflare-compression ``` ## 开源总仓库内容 [#开源总仓库内容] GitHub / Gitee 的 `flyfish-dev/file-viewer` 是开源总仓库,用于分发开源源码、Demo / 文档源码和 release 元数据。私有 Gitea 继续作为完整聚合仓、统一发布脚本、内部自动化和优先技术支持入口。仓库内容包括: * `packages/core/`: framework-neutral core 源码 * `packages/components/`: Vanilla JS / Pure Web、Vue、React、jQuery、Svelte 等标准组件包源码 * `packages/compat/`: 历史 npm 包名兼容 alias 源码 * `apps/`: 主 Demo 和组件 Demo 源码 * `dist/`: 混淆压缩后的组件库产物 * `docs/` + `apps/docs-site/`: Markdown 内容源与 Fumadocs + Next.js 文档应用 * `artifacts/`: release manifest、状态报告和可上传到 GitHub Release 的 tarball * `Dockerfile` / Docker Hub 标签: 可直接部署的静态镜像构建与发布信息 * `README.md`: 默认英文入口,便于 GitHub 与海外用户直接评估和接入 * `README.zh-CN.md`: 完整中文入口,与默认英文 README 互相提供语言切换链接 * `README.en.md`: npm 包与历史发布工具兼容使用的英文入口 * `LICENSE`: 项目许可证 其中 `README.md` 会承担开源总仓库首页职责,写明官方文档、在线 Demo、npm 包、私有化部署、源码目录、release 下载物和支持入口。`apps/`、`packages/` 和 `docs/` 默认保留源码,主 Demo、component demo、文档站和样例文件的构建产物不再作为顶层目录常驻提交,避免 GitHub clone 被静态站点和二进制样例拖大。需要下载站点产物时,从 GitHub Release 或 Cloudflare Pages 部署域名获取。 如果确实需要生成完整展开目录,可以显式使用 `FILE_VIEWER_PUBLIC_EXPANDED_ASSETS=1` 或 `--expanded-assets`。该模式只用于一次性交付、离线包检查或临时镜像排障,不作为公开 GitHub / Gitee 的默认发布形态。 开源总仓库会包含 `apps/`、`packages/core/`、`packages/components/`、`packages/compat/` 和 `docs/` 等源码,同时继续保留可直接部署或下载的 release 产物。 ## 发版命令 [#发版命令] 2.x 之后,生态包从完整聚合仓统一构建、校验和发布。发布前建议执行: ```bash pnpm type-check pnpm build pnpm build:vue3 pnpm obfuscate pnpm docs:build pnpm release:ecosystem:pack ``` 其中 `pnpm obfuscate` 会处理 `packages/components/vue3/dist/` 中的 `.js` / `.mjs` 文件。类型声明、CSS、图片和示例文件不会被混淆,便于业务方正常接入和排查。 正式发布前建议先执行: ```bash npm publish --dry-run --access public ``` 确认包名、版本、README 和 `dist/` 文件无误后,再执行 `npm publish --access public`。如果 npm 账号启用了 MFA,请使用交互式会话完成浏览器确认。 生态包发布: ```bash pnpm type-check:components pnpm build:component-demo pnpm release:ecosystem:list pnpm release:ecosystem:pack pnpm release:ecosystem:publish:dry-run pnpm release:ecosystem:publish ``` `release:ecosystem:pack` 会先构建 core、独立 renderer、preset、PPTX 原生引擎、标准组件包和历史兼容包,再统一打包本仓库当前 88 个 npm 目标。`@file-viewer/ppt` 作为独立版本依赖解析;其公开运行时由 Full/copy-assets/CDN 产物交付。发布前请确认 tarball 中包含必要的 viewer assets、`dist/*`、README / README.en.md,且没有 `.DS_Store`。 开源总仓库使用私有 Gitea `main` 完整聚合仓生成,发布前执行: ```bash pnpm release:public ``` 该命令会同步开源源码、混淆后的 `dist/`、release 元数据和生态 tarball,并在写入后自动执行 `pnpm verify:public-main`。默认不会把 Demo、component demo、文档静态产物和示例文件展开写入开源总仓;如需完整展开,请显式追加 `--expanded-assets`。如果只想检查已经生成的开源总仓库内容,可以执行: ```bash pnpm verify:public-main ``` 校验会反查 `artifacts/release-manifest.json`、`artifacts/release-status.json`、`artifacts/release-status.schema.json`、所有应公开 tarball、README / README.en.md、组件 GitHub / Gitee 索引和顶层目录边界,避免漏掉源码、重复 tarball 或发布过期产物。`release-manifest.json` 会通过 `metadataAssets` 索引 manifest、status 和 schema 三份元数据;`release-status.json` 的 `sourceBaseline` 会明确私有 Gitea `main` 才是完整原始聚合仓基线,本地 checkout 分支名只是执行上下文;`release-status.schema.json` 是状态报告的公开 JSON Schema,可用于 CI 或下载端判断哪些缺口是本地可修项、哪些是 npm / Gitee / GitHub 等外部发布阻塞。 ## Docker 镜像发布 [#docker-镜像发布] Docker 镜像用于一键部署主 Demo、零依赖 iframe 入口和文档比对页。发布前先确保 Docker Hub 已登录,并且当前账号对 `flyfishdev/file-viewer` 有推送权限: ```bash docker login DOCKER_IMAGE=flyfishdev/file-viewer pnpm docker:publish ``` 默认会推送 `latest` 和 `latest` 两个标签,并生成 `linux/amd64` / `linux/arm64` 多架构 manifest。发布后至少验证: ```bash docker run --rm -p 8080:80 flyfishdev/file-viewer:latest ``` 然后打开 `/`、`/iframe.html?url=/example/word.docx`、`/compare.html` 和 `/healthz`。 ## 授权和贡献 [#授权和贡献] 本仓库编写的 File Viewer 源码和软件包使用 `Apache-2.0` 许可证;完整发行物中随附的 `@file-viewer/ppt` 运行时保留自身独立 LICENSE 与 NOTICE,其他依赖也保留各自包内许可证,不会被 File Viewer 重新授权。二开或商用本仓库代码时,请保留许可证、版权和来源说明,并注明项目来源为 File Viewer by Flyfish / `@flyfish-group/file-viewer3` 或 `@flyfish-group/file-viewer`。 如果你修复了通用问题或增强了通用能力,建议通过 issue / PR 一起贡献回来。这样后续升级时,大家都能少走一点弯路。 --- # Docker 部署 (/zh/guide/docker) ## Docker Hub 一键运行 [#docker-hub-一键运行] 镜像发布后使用多架构 manifest,覆盖 `linux/amd64` 和 `linux/arm64`: ```bash docker run -d \ --name flyfish-viewer \ --restart unless-stopped \ -p 8080:80 \ flyfishdev/file-viewer:latest ``` 打开: * 主预览: `http://localhost:8080/` * iframe 嵌入: `http://localhost:8080/iframe.html?url=/example/word.docx` * 文档比对: `http://localhost:8080/compare.html` * 健康检查: `http://localhost:8080/healthz` 如果你希望始终使用最新稳定版本: ```bash docker run -d \ --name flyfish-viewer \ --restart unless-stopped \ -p 8080:80 \ flyfishdev/file-viewer:latest ``` ## Docker Compose [#docker-compose] ```yaml services: flyfish-viewer: image: flyfishdev/file-viewer:latest container_name: flyfish-viewer restart: unless-stopped ports: - "8080:80" healthcheck: test: ["CMD", "wget", "-qO-", "http://127.0.0.1/healthz"] interval: 30s timeout: 3s retries: 3 ``` 启动: ```bash docker compose up -d ``` ## 本地构建镜像 [#本地构建镜像] 源码仓库内提供标准 `Dockerfile`。本地只构建当前 CPU 架构并加载到 Docker: ```bash pnpm docker:build ``` 默认镜像名是 `flyfishdev/file-viewer`,标签为当前 `package.json` 版本和 `latest`。如需改成自己的命名空间: ```bash DOCKER_IMAGE=your-org/file-viewer pnpm docker:build ``` 本地运行: ```bash docker run --rm -p 8080:80 flyfishdev/file-viewer:latest ``` ## 通过 Docker Hub API 创建仓库 [#通过-docker-hub-api-创建仓库] 发布前先准备 Docker Hub Personal Access Token。仓库创建使用 Docker Hub API,镜像上传使用 Docker Registry 推送链路: ```bash DOCKER_IMAGE=flyfishdev/file-viewer \ DOCKERHUB_USERNAME=your-dockerhub-user \ DOCKERHUB_TOKEN=dckr_pat_xxx \ pnpm docker:repo:create ``` 脚本会先检查目标仓库是否存在;如果不存在,会调用 Docker Hub API 创建公开仓库。 ## 多架构推送到 Docker Hub [#多架构推送到-docker-hub] 仓库创建完成后登录 Docker Hub,并确认当前账号对目标 namespace 有推送权限。如果使用自己的命名空间,请把 `DOCKER_IMAGE` 改成对应仓库名: ```bash docker login ``` 推送 `linux/amd64` 和 `linux/arm64`: ```bash DOCKER_IMAGE=flyfishdev/file-viewer pnpm docker:publish ``` 脚本默认推送稳定入口标签: * `flyfishdev/file-viewer:latest` 如需覆盖平台或同时推送明确版本号,可以显式传入标签: ```bash DOCKER_IMAGE=flyfishdev/file-viewer \ DOCKER_PLATFORMS=linux/amd64,linux/arm64 \ DOCKER_TAGS=2.x.x,latest \ pnpm docker:publish ``` ## 镜像内容 [#镜像内容] Docker 镜像只包含构建后的静态产物,不携带源码工作区: * `/usr/share/nginx/html/index.html`: 主预览入口 * `/usr/share/nginx/html/iframe.html`: 无 Demo 外壳的 iframe 嵌入入口,兼容 `?url=` 与 `postMessage(Blob)` * `/usr/share/nginx/html/compare.html`: 文档比对入口 * `/usr/share/nginx/html/assets/*`: Vite hash 资源 * `/usr/share/nginx/html/example/*`: 示例文件 * `/usr/share/nginx/html/vendor/*`: Worker / WASM 等静态资源 nginx 配置会对 HTML 使用 `max-age=0, must-revalidate`,对 hash 资源和 vendor 资源使用长缓存,避免旧入口页引用已经不存在的异步 chunk。 ## 反向代理建议 [#反向代理建议] 如果容器前面还有网关或统一域名,建议保持以下路径不被重写: * `/` * `/iframe.html` * `/compare.html` * `/assets/*` * `/vendor/*` * `/example/*` 示例文件、WASM 和 Worker 都是静态资源;如果网关把缺失的 `.js` 或 `.wasm` 回退成 HTML,浏览器会触发 MIME 错误。生产环境请让这些资源缺失时返回真实 `404`。 --- # 生态组件总览 (/zh/guide/ecosystem) ## 导览 [#导览] | 技术栈 / 场景 | 推荐入口 | | --------------------- | ---------------------------------------------- | | 无框架页面、微前端壳、script 标签 | [纯 JS / Pure Web 集成](/zh/guide/quickstart-web) | | Vue 3 项目 | [Vue3 集成](/zh/guide/quickstart-vue3) | | Vue 2.7 / 2.6 项目 | [Vue2.7 / 2.6 集成](/zh/guide/quickstart-vue2) | | React 18 / 19 项目 | [React 集成](/zh/guide/quickstart-react) | | React 16.8 / 17 老项目 | [React Legacy 集成](#react-legacy) | | 传统 jQuery 后台 | [jQuery 集成](#jquery) | | Svelte / SvelteKit 项目 | [Svelte 集成](#svelte) | | 自研组件或深度二开 | [Core 自定义接入](#core) | | 单独验证 PPT / PPTX 渲染能力 | [PPT 与 PPTX 引擎接入](#ppt-与-pptx-引擎接入) | ## 安装策略 [#安装策略] 标准组件包是最轻入口。直接安装 `@file-viewer/vue3`、`@file-viewer/react`、`@file-viewer/web`、`@file-viewer/svelte`、`@file-viewer/jquery` 或 Vue2 组件包时,只会获得对应生态的原生组件体验、类型声明、controller 和 core 基础能力;具体格式能力由 preset 或单个 renderer 装配。 | 策略 | 安装方式 | 说明 | | ---------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | | 最轻组件入口 | `npm i @file-viewer/vue3` | 适合先接入组件壳、再按业务选择格式能力 | | 常见轻附件 | `npm i @file-viewer/vue3 @file-viewer/preset-lite` | 文本、Markdown、代码、图片、音频、视频,通过 `options.preset` 注入 | | 办公文档平台 | `npm i @file-viewer/vue3 @file-viewer/preset-office` | PDF、Word、Excel、PowerPoint、OFD、RTF、OpenDocument,推荐业务默认路线 | | 工程附件平台 | `npm i @file-viewer/vue3 @file-viewer/preset-engineering` | CAD、3D、绘图、XMind、Geo、Typst、Archive、Data、EDA | | 完整 Demo 能力 | `npm i @file-viewer/vue3 @file-viewer/preset-all` | 全量一键安装,适合演示站、后台运维和内部全格式附件中心 | | 完整 full 包 | `npm i @file-viewer/vue3-full` | 默认启用 `preset-all`,不需要手动传 `options.preset` | | CDN 完整体验 | `https://unpkg.com/@file-viewer/web-full@latest/dist/flyfish-file-viewer-web-full.iife.js` | 适合 script 标签试跑;二进制 `.ppt` 从包内 `vendor/ppt/` 自动加载,无需配置运行时 URL | | 极致裁剪 | `npm i @file-viewer/vue3 @file-viewer/renderer-pdf` | 只安装需要的 renderer,并通过 `options.renderers` 注入 | ## Full 包完整资产契约 [#full-包完整资产契约] 从 `2.1.30` 起,八个 Full 包使用同一套交付契约。它们已内置并启用 `preset-all`,同时携带版本对齐的 renderer、Worker、WASM、字体、Draw\.io、SQLite 等 vendor 资产;Vite 或随包 CLI 会把这份包内资产发布到业务自己的静态源。当前标准布局同时包含经过完整性校验的二进制 `.ppt` 0.3.4 公开运行时,以及按需加载的 EPUB 本地引擎和对应 NOTICE;两条链路都不需要运行时 CDN。 | 构建方式 | 完整部署方式 | | ----------------------------------- | --------------------------------------------------------------------------------------- | | Vite | 注册 `fileViewerRenderers({ copyAssets:true })`;插件会识别已安装的 Full 包,并在 dev/build 自动提供、复制全部资产 | | Webpack、Vue CLI、Rspack、Rollup、Umi 等 | 运行 `npx --no-install file-viewer-copy-assets ./public/file-viewer`;Full 包已带同版本 CLI | | script 标签 / CDN | 直接使用 jsDelivr/unpkg,或完整部署 `@file-viewer/web-full/dist/`;无需复制 | Full 包旁边不要再安装另一个 `preset-all` 或不同版本的资产复制工具。所有 Full 包默认访问部署基址下的 `file-viewer/`;只有静态目录不同才调用 `setDefaultFullAssetBaseUrl('/your-prefix/')`。 `options.preset` 是跨构建工具的稳定装配方式。Webpack、Rspack、Rollup、Umi、传统多页应用、微前端壳和内部组件库都可以显式 import preset,然后传给当前生态组件: ```ts import officePreset from '@file-viewer/preset-office' const viewerOptions = { preset: officePreset, rendererMode: 'replace' } ``` Vite 项目可以额外安装 `@file-viewer/vite-plugin` 省去手动 import。Vite 不会因为安装了插件包就自动运行,仍需要在 `vite.config.ts` 注册一次;注册后 `fileViewerRenderers()` 或 `fileViewerRenderers({ copyAssets:true })` 会自动发现已安装的 `@file-viewer/preset-*`,并把生成的 virtual module 注入 Vite HTML 入口。组件默认 `autoRenderers:true`,所以 Vue、React、Svelte、jQuery 和 Vanilla JS / Pure Web 都能直接获得对应预览能力。`preset-all` 能力最完整,但安装依赖也最多;生产业务建议优先选择 `preset-lite`、`preset-office`、`preset-engineering` 或单个 renderer。 ```ts // vite.config.ts import { fileViewerRenderers } from '@file-viewer/vite-plugin' export default { plugins: [ fileViewerRenderers({ copyAssets: true // 已安装的 preset 会自动激活,不需要手写 import 或 renderers。 }) ] } ``` ## 选型一览 [#选型一览] | 场景 | 推荐包 | 适合项目 | 入口能力 | | -------------------------- | --------------------------------- | ------------------------------ | --------------------------------------------------------------------------------------- | | 底层能力 | `@file-viewer/core` | 自研组件、二次封装、框架适配 | 纯 TypeScript 预览能力、格式矩阵、事件、搜索、缩放、打印、导出和共享类型 | | 二进制 PPT 运行时 | `@file-viewer/ppt@0.3.4` | 单独验证 PowerPoint 97–2003 `.ppt` | 独立版本依赖;Full/CDN 在 `vendor/ppt/` 交付公开运行时,与 PPTX Worker 严格分路 | | PPTX 引擎 | `@file-viewer/pptx` | 单独优化或验证 PPTX 渲染 | 独立 OpenXML 演示文稿引擎、Worker 渐进解析和样式文件 | | 轻量 preset | `@file-viewer/preset-lite` | 常见轻附件预览 | 文本、Markdown、代码、图片、音频和视频的轻量组合 | | 文档 preset | `@file-viewer/preset-office` | PDF / Office / OFD 文档平台 | PDF、Word、Excel、PowerPoint、OFD、RTF 和 OpenDocument | | 工程 preset | `@file-viewer/preset-engineering` | CAD、研发、设计、工程和 EDA 附件平台 | CAD、3D、绘图、XMind、Geo、Typst、Archive、Data 和 EDA | | 全量 preset | `@file-viewer/preset-all` | 官方 Demo、内部全格式附件中心 | 当前完整格式矩阵 | | Word renderer | `@file-viewer/renderer-word` | 只需要 DOCX/DOC/RTF/ODT 的业务 | 标准 renderer 插件,按需加载自研 DOCX、老 DOC 和 RTF/OpenDocument 链路 | | Vanilla JS / Pure Web | `@file-viewer/web` | 无框架页面、微前端壳、传统系统 | `` 原生组件、`mountViewer(container, options)`、IIFE script 标签包、资源复制 CLI | | Vanilla JS / Pure Web Full | `@file-viewer/web-full` | script 标签、POC、全格式传统页面 | 默认启用完整矩阵的 Custom Element、IIFE 和命令式挂载 | | Vue 3 | `@file-viewer/vue3` | Vue 3.3+ | Vue 插件、`` 组件、props、事件、ref/controller 和完整类型 | | Vue 3 Full | `@file-viewer/vue3-full` | Vue 3 全格式附件中心 | 默认启用完整矩阵,组件 API 与 `@file-viewer/vue3` 一致 | | Vue 2.7 | `@file-viewer/vue2.7` | Vue 2.7 项目 | `Vue.use(FileViewer)` 插件式注册,能力与 Vue 3 线保持一致 | | Vue 2.7 Full | `@file-viewer/vue2.7-full` | Vue 2.7 全格式附件中心 | 默认启用完整矩阵,适合存量 Vue2.7 项目快速升级 | | Vue 2.6 | `@file-viewer/vue2.6` | 仍停留在 Vue 2.6 的老项目 | Vue 2.6 专线,避免强迫业务升级到 2.7 | | Vue 2.6 Full | `@file-viewer/vue2.6-full` | Vue 2.6 全格式附件中心 | 默认启用完整矩阵 | | React 18/19 | `@file-viewer/react` | React 18 / 19,也兼容 React 17 | 原生 React 组件、`useFileViewer`、`useFileViewerState` 和 ref handle | | React 18/19 Full | `@file-viewer/react-full` | React 全格式附件中心 | 默认启用完整矩阵,组件和 hooks 体验与标准包一致 | | React 16.8/17 | `@file-viewer/react-legacy` | 旧 React hooks 项目 | 面向 React 16.8 / 17 的独立组件包 | | React 16.8/17 Full | `@file-viewer/react-legacy-full` | 旧 React 全格式附件中心 | 默认启用完整矩阵 | | jQuery | `@file-viewer/jquery` | 传统后台、jQuery 插件体系 | `$(el).fileViewer(options)` 和插件方法调用 | | jQuery Full | `@file-viewer/jquery-full` | 传统后台全格式附件中心 | 默认启用完整矩阵 | | Svelte | `@file-viewer/svelte` | Svelte / SvelteKit | Svelte 组件、action、事件和 controller 方法 | | Svelte Full | `@file-viewer/svelte-full` | Svelte 全格式附件中心 | 默认启用完整矩阵,组件与 action 入口保持一致 | 历史兼容包继续发布: `@flyfish-group/file-viewer3`、`file-viewer3`、`@flyfish-group/file-viewer`、`@flyfish-group/file-viewer-react`、`@flyfish-group/file-viewer-web`。新系统建议使用标准包名,便于理解依赖边界和后续迁移。 ## 架构边界 [#架构边界] * `@file-viewer/core` 是 framework-neutral 底座,不依赖 Vue、React、Svelte 或 jQuery。 * 各标准组件包只依赖 core 和自己的生态依赖,不嵌套其他框架实现。 * 所有组件包共享同一套 `ViewerMountOptions`、`FileViewerOptions`、生命周期事件、操作回调、搜索、缩放、水印、打印和导出语义。 * Office、PDF、OFD、Typst、CAD、压缩包、邮件、3D、绘图、数据文件等重型链路按格式异步加载,未命中的格式不会进入首屏。常见业务优先选 `preset-lite`、`preset-office`、`preset-engineering`,极致裁剪再安装单个 renderer。 * 私有化或内网部署时,运行 `file-viewer-copy-assets` 复制 Worker、WASM、PDF.js、Draw\.io、Typst WASM/字体、CAD、SQLite、压缩包和 Office 静态资源,运行时默认不依赖公共 CDN。 * 样式隔离由同一套 `options.styleIsolation` 控制。所有标准组件默认使用 Shadow DOM,避免宿主全局 CSS 破坏预览器;主题定制使用 `--file-viewer-*` tokens 和 `::part()`,仅旧版深层样式覆盖场景显式使用 `styleIsolation:'none'`。完整说明见 [样式隔离与主题定制](/zh/guide/style-isolation)。 ## 组件属性与定制入口 [#组件属性与定制入口] 下面是各标准组件包当前实际暴露的属性、事件和控制入口。需要 `buffer`、`name`、`type`、`size` 这类命令式挂载参数时,优先使用 Vanilla JS / Pure Web、React、Svelte、jQuery 或 Vue2 组件;Vue3 声明式组件保持 `url` / `file` / `options` 的轻入口,二进制来源建议包装成带扩展名的 `File` 后传入。 | 组件 | 实际属性 / 入口 | 事件入口 | 控制与定制入口 | | ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | | Vanilla JS / Pure Web `@file-viewer/web` | `` 属性 `src/url`、`filename/name`、`type`、`size`、`theme`、`toolbar`、`toolbar-position`、`watermark`、`search`、`options`;也支持 `mountViewer(...)` | `viewer-ready`、`viewer-event`、`viewer-state-change`、`viewer-error`、`onEvent`、`onStateChange`、`controller.subscribe()` | Custom Element 实例暴露完整 controller handle;IIFE script 标签自动注册元素,同时保留命令式挂载和资源复制 CLI | | Vue 3 `@file-viewer/vue3` | `url`、`file`、`options` | `load-start`、`load-complete`、`unload-start`、`unload-complete`、`operation-before`、`operation-cancel`、`operation-availability-change`、`search-change`、`location-change`、`zoom-change` | 模板 `ref` 暴露 `FileViewerExpose`,可调用下载、打印、导出、缩放、搜索、定位和文本切片 API | | Vue 2.7 `@file-viewer/vue2.7` | `url`、`file`、`buffer`、`name`、`filename`、`type`、`size`、`options`、`containerClass`、`containerStyle` | `viewer-event` / `viewerEvent` | 组件实例暴露 controller handle 全量方法 | | Vue 2.6 `@file-viewer/vue2.6` | 同 Vue 2.7 | `viewer-event` / `viewerEvent` | 独立 Vue 2.6 构建,不要求业务升级到 Vue 2.7 | | React `@file-viewer/react` | `ViewerMountOptions` + `div` 原生属性,如 `className`、`style`、`data-*`、`aria-*` | `onEvent`、`onStateChange` | `ref` 暴露 `FileViewerHandle`;`useFileViewer()` 返回 `ref`、`props`、`state`、`handle` | | React Legacy `@file-viewer/react-legacy` | 同 React 标准包 | `onEvent`、`onStateChange` | 面向 React 16.8 / 17 的独立组件包 | | jQuery `@file-viewer/jquery` | `$(el).fileViewer(ViewerMountOptions & { replace?: boolean })` | `onEvent`、`onStateChange` 或 `getFileViewerController(el).subscribe()` | 插件方法支持 `zoomIn`、`printRenderedHtml`、`searchDocument` 等;`replace:false` 可原地更新 | | Svelte `@file-viewer/svelte` | `ViewerMountOptions` + `className`、`containerStyle` | `on:viewerEvent`、`onEvent`、`onStateChange` | `bind:this` 暴露 controller handle;`use:fileViewer` action 额外支持 `replace` | ## 工具栏定制 [#工具栏定制] 内置工具栏适合大多数后台和附件中心场景;如果业务需要权限按钮、审计提示、设计系统菜单或移动端悬浮操作区,可以关闭内置工具栏,改用各生态原生 UI 调用同一套 controller API。 | 配置 | 说明 | | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | | `toolbar: false` | 隐藏内置工具栏,但不关闭下载、打印、导出、缩放等 API,适合完全自定义工具栏 | | `toolbar: true` | 使用默认工具栏,按钮仍按当前格式能力动态显隐 | | `toolbar.download` / `print` / `exportHtml` / `zoom` | 表达业务是否允许展示对应按钮;最终还会结合文件类型、渲染完成状态、导出适配器和缩放 provider 计算真实可用性 | | `toolbar.order` | 调整内置工具栏分组顺序,默认 `['search', 'zoom', 'download', 'print', 'exportHtml']`;例如 `['zoom', 'search', 'download', 'print']` 可让缩放排在搜索前,未列出的项按默认顺序追加 | | `toolbar.position` | `auto`、`top`、`top-center`、`bottom-right`。默认 `auto`,PDF 自动悬浮右下角,其他格式保持顶部靠右;需要顶部水平居中时传 `top-center` | | `toolbar.beforeOperation` | 工具栏层统一前置校验,会在 `options.beforeOperation` 后执行 | | `toolbar.beforeDownload` / `beforePrint` / `beforeExportHtml` | 单按钮前置校验,适合下载权限、打印审计和导出确认 | 自定义工具栏不要在预览器外层套 `transform: scale()`。PDF、Excel、CAD、canvas 和文本层格式都要通过内部缩放 provider 保持坐标正确。外部按钮应读取 `operation-availability-change` / `onStateChange` / `subscribe()` 的能力状态,动态禁用不可用操作。 ### Vue 3 自定义工具栏 [#vue-3-自定义工具栏] ```vue ``` ### React 自定义工具栏 [#react-自定义工具栏] ```tsx import FileViewer, { useFileViewer } from '@file-viewer/react' export function Preview() { const viewer = useFileViewer({ url: '/files/report.docx', options: { theme: 'light', toolbar: false } }) const availability = viewer.state.availability return (
) } ``` ### Vanilla JS / Pure Web / Script 标签 [#vanilla-js--pure-web--script-标签] ```html
``` 无构建工具时,引入 IIFE 后直接写 `` 即可;`window.FlyfishFileViewerWeb.mountViewer(...)` 仍可用于完全命令式场景。 ### Vue 2、jQuery 和 Svelte [#vue-2jquery-和-svelte] ```vue ``` ```ts // jQuery import { getFileViewerController } from '@file-viewer/jquery' $('#viewer').fileViewer({ url: '/files/report.xlsx', options: { toolbar: false } }) $('#zoomIn').on('click', () => $('#viewer').fileViewer('zoomIn')) getFileViewerController($('#viewer'))?.subscribe((state) => { $('#zoomIn').prop('disabled', !state.availability?.zoomIn) }) ``` ```svelte { if (event.detail.type === 'operation-availability-change') { availability = event.detail.payload } }} /> ``` ## Vue 3 [#vue-3] ```bash pnpm add @file-viewer/vue3 ``` ```ts import { createApp } from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue3' createApp(App).use(FileViewer).mount('#app') ``` ```vue ``` ## Vue 2.7 / Vue 2.6 [#vue-27--vue-26] Vue 2.7: ```bash pnpm add @file-viewer/vue2.7 ``` Vue 2.6: ```bash pnpm add @file-viewer/vue2.6 ``` ```ts import Vue from 'vue' import App from './App.vue' import FileViewer from '@file-viewer/vue2.7' Vue.use(FileViewer) new Vue({ render: h => h(App) }).$mount('#app') ``` 历史 Vue 2 包 `@flyfish-group/file-viewer` 仍对应 Vue 2.7 线。新项目如果无法升级 Vue,先按运行时版本选择 `@file-viewer/vue2.7` 或 `@file-viewer/vue2.6`。 ## React [#react] ```bash npm install @file-viewer/react ``` ```tsx import { useRef } from 'react' import FileViewer, { type FileViewerHandle } from '@file-viewer/react' export function Preview() { const viewerRef = useRef(null) return (
console.log(event.type, event.payload)} />
) } ``` 需要状态同步时可以使用 `useFileViewer`: ```tsx import FileViewer, { useFileViewer } from '@file-viewer/react' export function SearchablePreview() { const viewer = useFileViewer({ url: '/files/report.docx', options: { search: true } }) return ( <>
) } ``` ### React Legacy [#react-legacy] React 16.8 / 17 的旧项目可改用 `@file-viewer/react-legacy`,API 保持同一套 props 与 controller 语义。 ## Vanilla JS / Pure Web [#vanilla-js--pure-web] ```bash npm install @file-viewer/web ``` ```html ``` 无构建工具页面可以使用 IIFE: ```html ``` `@file-viewer/web` 还提供 `file-viewer-copy-assets`,用于把离线资源复制到业务静态目录。 ## jQuery [#jquery] ```bash npm install jquery @file-viewer/jquery ``` ```ts import $ from 'jquery' import { installJQueryFileViewer } from '@file-viewer/jquery' installJQueryFileViewer($) $('#viewer').fileViewer({ url: '/files/demo.pdf', options: { theme: 'light', toolbar: { position: 'bottom-right' } } }) $('#viewer').fileViewer('searchDocument', '发票') $('#viewer').fileViewer('zoomIn') ``` 如果页面已经有全局 jQuery,插件包会尽量自动挂载;显式调用 `installJQueryFileViewer($)` 更稳,也更适合模块化项目。 完整格式矩阵使用 `@file-viewer/jquery-full`,无需再 import preset。Vite 保持 `copyAssets:true`;非 Vite jQuery 项目运行 Full 包自带的 `npx --no-install file-viewer-copy-assets ./public/file-viewer`。 ## Svelte [#svelte] ```bash npm install @file-viewer/svelte ``` ```svelte
console.log(event.detail.type)} />
``` 也可以在普通 DOM 节点上使用 action: ```svelte
``` SvelteKit 中请确保预览器只在浏览器端挂载,并给容器稳定高度;服务端渲染阶段不要访问 `window`、`document` 或真实文件对象。 完整格式矩阵使用 `@file-viewer/svelte-full`,无需再 import preset。SvelteKit/Vite 保持 `copyAssets:true`;其它构建链运行 Full 包自带的 `npx --no-install file-viewer-copy-assets ./public/file-viewer`。 ## Core 自定义接入 [#core-自定义接入] 业务如果要做自己的组件层,可以直接依赖 `@file-viewer/core`,但建议只有在标准组件包无法覆盖交互模型时才这么做。 ```bash npm install @file-viewer/core ``` Core 暴露格式矩阵、资源路径解析、搜索/缩放/打印导出工具、生命周期上下文和渲染器注册能力。上层组件应只负责容器、状态管理、事件桥接和生态交互,不要把 Vue / React / Svelte 运行时下沉到 core。 ## PPT 与 PPTX 引擎接入 [#ppt-与-pptx-引擎接入] ```bash npm install @file-viewer/pptx ``` `@file-viewer/renderer-presentation` 对外提供统一演示文稿能力,但内部保持两条严格隔离的引擎:PowerPoint 97–2003 `.ppt` 使用 `@file-viewer/ppt@0.3.4` 原生 WASM,PPTX/OpenXML 使用 `@file-viewer/pptx` Worker。两者都不会进入 core-only 安装。标准 Vanilla JS / Pure Web、Vue、React、jQuery 和 Svelte 项目应优先安装 presentation renderer,或通过 `preset-office` / `preset-all` 获得完整路由;只有自研 renderer 时才直接调用底层引擎。 ```bash npm install @file-viewer/ppt@0.3.4 @file-viewer/pptx ``` ## 离线资源 [#离线资源] 所有生态包都可以使用同一套离线资源复制流程: ```bash npx --yes file-viewer-copy-assets ./public/file-viewer ``` 发布后确认这些路径能直接访问,并且 `.wasm`、`.mjs`、Worker 脚本不会被网关回退为 HTML: | 资源 | 默认目录 | | -------------------------------------------- | --------------------------------------------------------- | | PDF.js worker / CMap / WASM / standard fonts | `file-viewer/vendor/pdf/` | | Draw\.io 官方离线 viewer | `file-viewer/vendor/drawio/` | | CAD DWG / DWF / DWFx WASM | `file-viewer/wasm/cad/` | | Typst compiler / renderer WASM / 默认字体 | `file-viewer/wasm/typst/`、`file-viewer/wasm/typst/fonts/` | | SQLite WASM | `file-viewer/wasm/sqlite/` | | libarchive Worker / WASM | `file-viewer/vendor/libarchive/` | | Office Worker | `file-viewer/vendor/docx/`、`file-viewer/vendor/xlsx/` | ## 统一 API [#统一-api] | 能力 | 说明 | | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | | 输入 | `url`、`file`、`buffer`、`name`、`filename`、`type`、`size` | | 事件 | `onEvent` / `viewerEvent`,包含加载开始、加载完成、卸载开始、卸载完成、错误、搜索、缩放、fit、位置变化等上下文 | | 状态 | React `useFileViewerState`、controller `subscribe()`,其他生态可通过事件和 controller 获取 | | 操作 | `downloadOriginalFile()`、`printRenderedHtml()`、`exportRenderedHtml()`、`zoomIn()`、`zoomOut()`、`resetZoom()`、`fitToView()` | | 搜索定位 | `searchDocument()`、`clearDocumentSearch()`、`nextSearchResult()`、`previousSearchResult()`、`collectDocumentAnchors()`、`scrollToAnchor()`、`scrollToLine()` | | AI 友好能力 | `getDocumentTextChunks()` 返回文本块、页码、行号、锚点和 label 上下文,业务侧可用于向量化、溯源和召回高亮 | | 权限前置 | `options.beforeOperation` 可在下载、打印、导出、缩放等操作前返回 `true` / `false` 或 Promise,便于做权限校验 | ## 推荐决策 [#推荐决策] * Vue 项目优先使用对应 Vue 标准包,不建议把 Vanilla JS / Pure Web 包再包一层组件。 * React 项目优先使用 `@file-viewer/react`;React 16.8 / 17 老项目用 `@file-viewer/react-legacy`。 * Svelte、jQuery 和普通 HTML 页面都有独立入口,不需要借用 Vue 组件。 * 内网部署先把 viewer assets 复制到业务静态目录,再根据网关路径覆盖 `options.pdf.*`、`options.cad.*`、`options.typst.*`、`options.archive.*` 等资源地址。 * 所有生态都要给父容器稳定高度;如果传入 `Blob` / `ArrayBuffer`,请同时提供带扩展名的 `name` 或包装成 `File`。 --- # 常见问题 (/zh/guide/faq) ## 不同生态应该安装哪个包 [#不同生态应该安装哪个包] 新项目优先选择 `@file-viewer/*` 标准包名: | 项目生态 | 推荐包 | | --------------------------------- | --------------------------- | | Vue3 | `@file-viewer/vue3` | | Vue2.7 | `@file-viewer/vue2.7` | | Vue2.6 | `@file-viewer/vue2.6` | | React 18/19 | `@file-viewer/react` | | React 16.8/17 | `@file-viewer/react-legacy` | | Vanilla JS / Pure Web / script 标签 | `@file-viewer/web` | | jQuery | `@file-viewer/jquery` | | Svelte / SvelteKit | `@file-viewer/svelte` | | 自研组件或深度二开 | `@file-viewer/core` | 历史包名 `@flyfish-group/file-viewer3`、`file-viewer3`、`@flyfish-group/file-viewer`、`@flyfish-group/file-viewer-react`、`@flyfish-group/file-viewer-web` 仍会同步维护,主要用于旧项目不改包名升级。 所有包线的格式能力、示例文件、`file` / `url` 参数行为、options、事件和类型语义保持一致。Vanilla JS / Pure Web、Vue3、Vue2、React、jQuery 和 Svelte 都是各自生态的原生接入,不需要借用其他框架组件。 `*-full` 已内置 `preset-all`,但 Worker、WASM、字体和 vendor 文件仍必须发布到静态目录。Vite 项目使用 `@file-viewer/vite-plugin` 的 `copyAssets: true`;其他构建工具运行 full 包自带的同版本 `npx --no-install file-viewer-copy-assets ./public/file-viewer`。默认访问路径为 `<部署基址>/file-viewer/`,根部署即 `/file-viewer/`。 ## full 包安装后还需要复制 assets 吗 [#full-包安装后还需要复制-assets-吗] 不一定需要手动复制。Full 不会把 PDF Worker、CAD/Typst/Archive WASM、字体等二进制资源内联进业务 JavaScript,因此完整格式支持必须发布这些同版本资产;但从 `2.1.30` 起,Vite 自动处理,完整 `web-full/dist/` 也已自带资产,只有非 Vite 入口构建需要执行一次 CLI。 * Vite:启用 `fileViewerRenderers({ copyAssets: true })`,开发和构建都会把匹配当前 full 包的资源发布到 `<部署基址>/file-viewer/`。 * Webpack、Vue CLI 等:直接运行 full 包自带的 `npx --no-install file-viewer-copy-assets ./public/file-viewer`。 * 自定义静态前缀:启动时调用 full 包导出的 `setDefaultFullAssetBaseUrl()`。 * CDN / IIFE:完整部署 `@file-viewer/web-full/dist/` 时 assets 已在目录内,无需再复制;只复制入口 IIFE 文件不完整,可运行随包 CLI。 不要单独安装另一个版本的 `preset-all` 或复制工具,否则容易出现 API、Worker 和 WASM 版本不一致。 ## 如何确认 DOCX 0.3.31 修复已经生效 [#如何确认-docx-0331-修复已经生效] 当前 Word renderer 的主线程和离线 Worker 均使用 `@file-viewer/docx@0.3.35`。它包含日文文字、VML 文本框、Apache POI `w:hMerge`、多分节浮动图形、复杂框架、定位页面、修订、段落标记和软换行修复,并默认阻断文档中的外部资源。 升级后需要重新发布同版本 viewer assets,并在浏览器网络面板确认 `vendor/docx/docx.worker.js?file-viewer-docx=0.3.35`(可能位于自定义 `file-viewer/` 基址下)真实返回 JavaScript。不要混用旧版本 Worker;如果仍看到旧布局,请清理 CDN 或 Service Worker 缓存后重新加载文档。 ## npm 11 安装时报 `Cannot read properties of null (reading 'matches')` [#npm-11-安装时报-cannot-read-properties-of-null-reading-matches] 这通常不是 `@file-viewer/*` 包版本不匹配。我们已经用 npm 11.17.0 在干净临时目录验证过 registry 安装和本地 tgz 依赖闭包安装,`@file-viewer/vue3 + @file-viewer/preset-office` 均可正常安装和导入。 这个错误来自 npm 内部 Arborist 构建依赖树时访问了空的 link target,常见触发原因是同一个项目目录里先用 pnpm、bun、vlt 等包管理器生成过 `node_modules`,之后又执行 `npm install`。npm 看到 store-style symlink 时可能直接抛出 `matches` 的 TypeError,而不是给出清晰提示。 建议按以下顺序处理: ```bash # 如果项目决定使用 npm rm -rf node_modules package-lock.json npm-shrinkwrap.json npm cache verify npm install ``` ```bash # 如果项目原本使用 pnpm,请保持同一个包管理器 rm -rf node_modules package-lock.json pnpm install ``` 离线 tgz 场景也要注意:只安装一个顶层 tgz 时,它的依赖仍需要能从 npm registry、私有 registry 或同目录依赖 tarball 中解析到。企业内网建议把 `@file-viewer/vue3`、所选 preset、preset 内部 renderer、`@file-viewer/core` 等同版本 tarball 一起放入私有 npm 源,或在安装命令/业务 package.json 中同时声明这些本地 tgz。 项目内置了安装烟测命令,发布前可复核 npm 最新版兼容性: ```bash pnpm verify:npm-install-smoke ``` ## URL 预览为什么失败或空白 [#url-预览为什么失败或空白] 组件在浏览器里通过 `axios` 请求目标文件,所以最常见的失败原因是: * 文件地址本身不可访问 * 服务端没有正确配置 CORS * 鉴权信息只能在宿主系统内使用,浏览器直接请求拿不到文件 如果你的场景带有登录态、签名 URL 或内部权限体系,优先由业务侧先完成鉴权下载,再使用 `file` + `name` 参数预览。 ## React 或纯 JS 集成后为什么页面空白 [#react-或纯-js-集成后为什么页面空白] 最常见原因是父容器没有稳定高度,或者传入的二进制缺少 `name`,导致无法判断格式。请先检查: * 容器是否有明确高度,例如 `height: 100vh` * `file` 是 `Blob` / `ArrayBuffer` 时是否同时传入 `name` * `url` 是否能被浏览器直接访问,且服务端正确返回 CORS * 控制台是否有 worker/WASM 的 MIME 或 CSP 报错 如果报错来自 archive、CAD、Typst 等重型资源路径,请发布并自托管资源: ```bash npx --yes file-viewer-copy-assets ./public/file-viewer ``` ## 为什么带查询参数的下载地址有时识别不到格式 [#为什么带查询参数的下载地址有时识别不到格式] 当前预览器会根据文件名扩展名判断该走哪条渲染链路。如果 URL 形如 `/download?id=123`,路径里没有明确的 `.pdf`、`.docx`、`.xlsx` 这类后缀,渲染器就很难准确识别文件类型。 这类地址最稳妥的做法是: * 先在业务侧请求文件 * 拿到 `Blob` 或 `ArrayBuffer` * 再包装成带正确文件名的 `File` ## 为什么一定要给父容器设置高度 [#为什么一定要给父容器设置高度] 预览器默认使用 `width: 100%` 和 `height: 100%` 填满父容器。如果父容器没有稳定高度,渲染区域就会塌陷,看起来像“没有内容”。 ## `file` 和 `url` 同时传时,谁优先 [#file-和-url-同时传时谁优先] 当前行为是 `file` 优先。如果后续把 `file` 清空,而 `url` 仍然存在,组件会回退到 `url` 再次加载。 ## `.doc` 和 `.docx` 的渲染实现一样吗 [#doc-和-docx-的渲染实现一样吗] 不一样。 * `docx` 由 `@file-viewer/renderer-word` 调用自研 `@file-viewer/docx` * `doc` 由 `@file-viewer/renderer-word` 调用 `msdoc-viewer` 另外,`.doc` 还额外套了一层 Word 风格页面容器,让页面在灰色背景中居中展示。 ## `Blob` 或 `ArrayBuffer` 能直接传给 `file` 吗 [#blob-或-arraybuffer-能直接传给-file-吗] 从接入经验上看,不建议直接把裸 `Blob` 或 `ArrayBuffer` 塞进去。 原因很简单: 预览器要靠文件名扩展名来选择渲染器,而裸二进制本身通常不带可靠的文件名。更稳妥的方式是: ```ts const file = new File([blobOrBuffer], 'report.xlsx') ``` 这样既保留了二进制链路,也把渲染器最依赖的扩展名补齐了。 ## `xls` 和 `xlsx` 的样式能力有什么差异 [#xls-和-xlsx-的样式能力有什么差异] 当前表格预览由 `@file-viewer/renderer-spreadsheet` 承接,内部统一走 `styled-exceljs`,会读取文件里能表达的列宽、行高、合并单元格、边框、填充和对齐等信息。差异主要来自格式本身: `xlsx` 通常保存的样式信息更完整,而 `xls/csv/ods` 等格式可能缺少部分现代样式描述。 ## `html` 文件为什么是按文本显示的 [#html-文件为什么是按文本显示的] 因为当前版本把 `html` 放在代码/文本类型里处理,它会展示并高亮源内容,而不会把文件当作网页直接执行。这是为了保证预览行为更安全、更可控,也更适合代码和模板查看。 ## DWG 能直接预览吗 [#dwg-能直接预览吗] 可以。CAD 预览当前使用 `@flyfish-dev/cad-viewer`,DWG 会通过独立 Worker 加载 LibreDWG WASM,在浏览器本地解析图层、块参照和常见几何实体;DXF 使用 JavaScript parser;DWF / DWFx / XPS 使用 native `dwf-viewer` 渲染 W2D/W3D/XPS 图形。 私有化部署时请确认 viewer assets 目录下的 `wasm/cad/libredwg-web.js`、`wasm/cad/libredwg-web.wasm`、`wasm/cad/dwfv-render.wasm` 和 `wasm/cad/dwg-worker.js` 能被静态服务直接访问,且 `.wasm` 不要被网关回退成 HTML。路径不同可以通过 `options.cad.wasmPath`、`options.cad.workerUrl` 和 `options.cad.dwfWasmUrl` 覆盖。 ## 3D 模型支持哪些格式 [#3d-模型支持哪些格式] 3D 模型走 `@file-viewer/renderer-3d` 按需渲染,当前支持 `glb`、`gltf`、`obj`、`stl`、`ply`、`fbx`、`dae`、`3ds`、`3mf`、`amf`、`usd`、`usda`、`usdc`、`usdz`、`kmz`、`pcd`、`wrl`、`vrml`、`xyz`、`vtk`、`vtp`。如果模型依赖外部贴图、材质或 `.bin`,远程 URL 预览会按原文件目录继续加载;本地上传建议优先使用单文件 `.glb`。 `step` / `stp`、`iges` / `igs` 和 `brep` 已经可以直接预览:文件在本地 OCCT Worker/WASM 中解析,生成真实网格后支持轨道控制、适配视图和统一缩放,不需要私有服务端转换。私有化部署需保留 `wasm/model/occt-worker.js`、`wasm/model/occt-import-js.js` 和 `wasm/model/occt-import-js.wasm`;子路径可用 `options.model.workerUrl`、`options.model.runtimeUrl`、`options.model.wasmUrl` 覆盖。IFC 需要显式安装并注册实验性的 `@file-viewer/renderer-3d/ifc`,再自托管匹配的 That Open / `web-ifc` Worker、WASM 和许可证资产;它不进入默认 preset 或 Full 包。`3dm` 仍只提供签名识别和专业内核接入说明。 ## Excalidraw 和 draw\.io 是怎么预览的 [#excalidraw-和-drawio-是怎么预览的] `.excalidraw` 默认走 `roughjs` 只读 SVG 预览,运行环境已提供官方 `@excalidraw/excalidraw` ESM 模块时会优先尝试 `exportToSvg`;`.drawio` / `.dio` 默认走不执行文档 HTML 的内置 SVG 安全预览。只有显式设置 `options.drawing.preferOfficial = true` 时才在无 same-origin 权限、带严格 CSP 的 iframe 中加载单独分发的 diagrams.net `GraphViewer`;该能力的 styles、shapes、stencils、img、mxgraph 和 math 路径全部指向同源本地资源,不访问公共 CDN,加载失败或超时仍会回退到内置 SVG。 diagrams.net 官方仓库没有维护最新 npm viewer 包;官方文档推荐的离线集成方式就是复制仓库里的 `viewer-static.min.js` 自托管。项目内置的是官方 `v30.2.5` release 的 viewer 文件和配套资源,不使用已经滞后的第三方 `drawio-offline` 包。 ## 压缩包能预览到什么程度 [#压缩包能预览到什么程度] 压缩包优先走独立的 `@file-viewer/renderer-archive`,内部使用 `libarchive.js` 的 WASM Worker,支持 ZIP、7z、RAR、TAR、GZIP、BZIP2、XZ、CAB、ISO、JAR、APK、CBZ/CBR 等入口。组件先读取目录,用户点击内部文件后才按需解压,避免一次性把大包展开到主线程。 内部文件会继续复用统一预览器,所以压缩包里的 PDF、Office、Markdown、代码、图片、邮件或嵌套压缩包都可以在体积限制内打开。私有化部署默认会先尝试当前部署 base 下的 `vendor/libarchive/worker-bundle.js`;如果手机 WebView、本地临时服务器、MIME 或 CSP 导致 Worker 初始化超时,还会切换到 ZIP/TAR/GZIP 兼容模式。旧系统生成、未声明 UTF-8 的 ZIP 中文文件名会自动按 GBK/GB18030 兼容解码,避免目录名乱码。只有静态目录或 WASM 位置特殊时,才需要通过 `options.archive.workerUrl` / `options.archive.wasmUrl` 指定路径。 ## full 包仍提示 libarchive Worker 未加载怎么办 [#full-包仍提示-libarchive-worker-未加载怎么办] 所有 full 包默认会把 Archive、PDF、DOCX、Excel、二进制 PPT、PPTX、CAD、Typst、Draw\.io、SQLite 等离线资产指向部署基址下的 `file-viewer/`。根部署时,请确认这两个示例 URL 真实返回 JavaScript/WASM,而不是网关 404 或 SPA HTML 回退: * `/file-viewer/vendor/libarchive/worker-bundle.js` * `/file-viewer/vendor/libarchive/libarchive.wasm` 如果资源不在部署基址下的 `file-viewer/`,在应用启动前调用: ```ts import { setDefaultFullAssetBaseUrl } from '@file-viewer/react-full' setDefaultFullAssetBaseUrl('/your-static-prefix/') ``` 兼容模式提示并不代表 ZIP/TAR/GZIP 完全不可用;它表示 libarchive Worker 当前没启动成功,RAR、7z、加密压缩包等仍需要发布上述 Worker/WASM。ZIP、TAR、GZIP 会优先走兼容路径,旧 GBK/GB18030 中文 ZIP 文件名也会继续正确解码。 ## 能否完全离线部署,不访问公共 CDN [#能否完全离线部署不访问公共-cdn] 可以。预览运行时默认不依赖公共 CDN 或第三方在线静态资源。full 包必须通过 Vite 插件或同版本 `file-viewer-copy-assets` 把 PDF.js worker/CMap/WASM/standard fonts、Draw\.io 官方 viewer 资产、CAD WASM、Typst WASM/字体、SQLite WASM、压缩包 worker 和 Office worker 发布到业务静态目录。路径特殊时使用 full 包的 `setDefaultFullAssetBaseUrl()`,或使用 `options.pdf.*`、`options.drawing.viewerScriptUrl`、`options.cad.*`、`options.typst.*`、`options.data.sqlWasmUrl`、`options.archive.*`、`options.docx.workerUrl`、`options.docx.workerJsZipUrl`、`options.spreadsheet.workerUrl` 指向自托管资源。 Typst 本地 WASM 或默认字体目录不可用、浏览器端编译超时时会显示明确错误,不会切换源码预览,也不会为了兜底访问外部站点;Draw\.io 官方离线 viewer 不可用时会切换内置 SVG 预览;地理数据默认使用离线 MapLibre 矢量地图,WebGL 不可用时回退 SVG 预览。 ## 邮件和 EDA 文件怎么预览 [#邮件和-eda-文件怎么预览] 邮件链路由 `@file-viewer/renderer-email` 独立承接。`.eml` / `.mbox` 使用 `postal-mime`,`.msg` 使用 `@kenjiuno/msgreader`。邮件预览会展示头信息、HTML/文本正文和附件列表;附件可以下载,也可以继续交给统一预览器打开。HTML 正文会放进隔离沙箱文档,不执行脚本。 `.olb` / `.dra` / `.gds` / `.oas` / `.oasis` 由 `@file-viewer/renderer-eda` 独立承接。OLB / DRA 使用 `cfb` 解析常见 OrCAD / Allegro 复合文档容器,展示结构树、元件/封装/Padstack 候选、属性、诊断、文本片段和可读字符串;标准 GDSII 会生成 SVG / WebGL 快速版图;OASIS 文本夹具可生成 SVG,真实 SEMI 二进制 OASIS 先做安全结构索引。它适合做附件初筛,不替代专业 EDA 软件里的封装编辑、电气规则校核或制造输出。 ## 水印、打印和导出怎么配置 [#水印打印和导出怎么配置] 通过 `options` 配置即可。`options.watermark` 支持文字或图片水印,`options.toolbar` 可以控制下载原文件、打印完整渲染内容、导出渲染后 HTML、统一缩放按钮和操作栏位置。`toolbar.zoom` 可关闭缩放按钮;不要在宿主外层用 CSS transform 强行缩放预览器,PDF、表格、CAD、canvas 和文本层可能出现坐标偏移。`toolbar.position` 支持 `auto`、`top`、`top-center`、`bottom-right`,默认 `auto`,PDF 会自动悬浮到右下角以避开自身导航栏;需要顶部水平居中时传 `top-center`。打印按钮会按当前文件类型、渲染完成状态和导出适配器动态显隐;表格、压缩包、邮件、EPUB、音视频、3D / 模型等不适合直接打印的链路会自动隐藏。打印和 HTML 导出不会修改原始文件;Word / PDF 会通过专属导出适配器生成完整页面,避免只打印当前视口、当前页或被滚动容器裁切。 ## 为什么 PDF 打印不是当前屏幕截图 [#为什么-pdf-打印不是当前屏幕截图] 从 `1.0.19` 起,PDF 的打印和导出 HTML 不再克隆当前可见 canvas,而是重新按页生成完整 PDF 页面。这样即使用户只滚动到第一页、开启了导航窗格,或当前视口里只渲染了部分页面,打印窗口和导出的 HTML 仍然会包含完整页序。Word / DOC 现在也会走独立导出页面,避免 Demo 容器样式、滚动高度或缩放状态导致只打印第一页。 ## EPUB、UMD 和音频是怎么预览的 [#epubumd-和音频是怎么预览的] `.epub` 由 `@file-viewer/renderer-epub` 独立承接。v2.3.0 的阅读引擎是包内固化、按需加载并附带 NOTICE 的本地 vendor 资产,不会从公网加载,也不会把旧版 XML 解析依赖带进业务生产依赖树。阅读区默认使用滚动文档模式,兼容性比超宽分页布局更稳,避免部分浏览器出现正文白板。当前不内置 Kindle 专有格式或 DRM 电子书解析,建议在业务侧转换为 EPUB / PDF。 `.umd` 走独立 UMD 电子书解析器。前端生态里没有可靠维护的 UMD 阅读整库,所以组件按文件结构解析元数据、章节偏移、章节标题和 zlib 正文段,并用 `pako` 解压正文后按 UTF-16LE 展示。 音频文件走浏览器原生 `