π English | δΈζ
π Live Demo: https://mvp-onlyoffice.vercel.app/
A browser-based document processing solution built on the OnlyOffice technology stack, supporting document viewing, editing, and conversion entirely on the client side. All operations are performed on the user's device without requiring backend services.
- π‘οΈ Data Security: Document processing is completed entirely within the browser, data never leaves the local environment
- π Format Compatibility: Comprehensive support for mainstream office document formats including Word, Excel, PowerPoint, and more
- π Instant Response: Provides smooth document editing interaction experience
- π» Zero Deployment Cost: Client-side architecture, no server setup required
- β‘ Quick Start: Access the page and use immediately, no additional configuration needed
- π Internationalization: Built-in multi-language interface with free language switching
- π― Multi-Instance Support: Supports running multiple independent editor instances simultaneously with complete resource isolation
- Visit the Online Editor
- Select editor type:
/excel/base- Excel spreadsheet editor/docs/base- Word document editor/ppt/base- PowerPoint presentation editor/multi/base- Multi-instance basic demo (running multiple editors simultaneously)/multi/tabs- Multi-instance Tab demo (with cache management)
- Upload local files
- Edit document content directly in the browser
- Export and save the document after editing
| Parameter | Description | Values | Priority |
|---|---|---|---|
locale |
Specify interface language | en, zh |
- |
Usage Example:
# Set English interface
?locale=enThe editor manager provides a complete document operation interface, supporting core functions such as creation, destruction, and export. Supports both single-instance and multi-instance modes.
import { editorManagerFactory } from '@/onlyoffice-comp/lib/editor-manager';
// Get default instance
const editorManager = editorManagerFactory.getDefault();
// Check if editor has been created
const exists = editorManager.exists();
// Get editor instance
const editor = editorManager.get();
// Destroy editor
editorManager.destroy();import { editorManagerFactory } from '@/onlyoffice-comp/lib/editor-manager';
// Create or get instance with specified container ID
const manager1 = editorManagerFactory.create('editor-1');
const manager2 = editorManagerFactory.create('editor-2');
// Get instance with specified container ID
const manager = editorManagerFactory.get('editor-1');
// Get all instances
const allManagers = editorManagerFactory.getAll();
// Destroy specified instance
editorManagerFactory.destroy('editor-1');
// Destroy all instances
editorManagerFactory.destroyAll();Document export uses an event-driven mechanism with asynchronous communication through EventBus.
Export Process:
- Trigger Save: Call the
editorManager.export()method - Wait for Event: System listens for
saveDocumentevent - Get Data: Returns document binary data after event is triggered
Code Example:
// Single-instance mode
const editorManager = editorManagerFactory.getDefault();
const result = await editorManager.export();
// result contains: { fileName, fileType, binData, instanceId, media }
// Multi-instance mode
const manager1 = editorManagerFactory.get('editor-1');
const result1 = await manager1.export();
// result1.instanceId will match manager1.getInstanceId()
// Process export data
const blob = new Blob([result.binData], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
const url = window.URL.createObjectURL(blob);
// Perform download or other operationsMulti-Instance Export Mechanism:
In multi-instance mode, each EditorManager instance's export() method automatically filters SAVE_DOCUMENT events, only receiving save events belonging to the current instance (matched via instanceId field). This ensures that even when multiple instances call export() simultaneously, there will be no event confusion or data misalignment.
// Set to read-only mode
await editorManager.setReadOnly(true);
// Switch to editable mode
await editorManager.setReadOnly(false);
// Query current mode
const isReadOnly = editorManager.getReadOnly();The project uses an event bus mechanism to handle editor state changes and document operation events.
saveDocument- Document save completion eventdocumentReady- Document load ready eventloadingChange- Loading state change event
import { onlyofficeEventbus } from '@/onlyoffice-comp/lib/eventbus';
import { ONLYOFFICE_EVENT_KEYS } from '@/onlyoffice-comp/lib/const';
// Listen for document save event
onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT, (data) => {
console.log('Document saved:', data);
});
// Listen for document ready event
onlyofficeEventbus.on(ONLYOFFICE_EVENT_KEYS.DOCUMENT_READY, (data) => {
console.log('Document ready:', data);
});
// Remove event listener
onlyofficeEventbus.off(ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT, callback);
// Wait for event trigger (returns Promise)
const saveData = await onlyofficeEventbus.waitFor(
ONLYOFFICE_EVENT_KEYS.SAVE_DOCUMENT,
3000 // Timeout (milliseconds)
);Document conversion functionality is implemented based on WebAssembly, supporting conversion between multiple formats.
import { convertBinToDocument, createEditorView } from '@/onlyoffice-comp/lib/x2t';
// Single-instance mode: Create editor view (using default container)
await createEditorView({
file: fileObject, // File object (optional)
fileName: 'document.xlsx', // File name
isNew: false, // Whether to create new document
readOnly: false, // Whether read-only
lang: 'en', // Interface language
});
// Multi-instance mode: Create editor view (specify container ID)
const manager1 = await createEditorView({
file: fileObject,
fileName: 'document.xlsx',
isNew: false,
readOnly: false,
lang: 'en',
containerId: 'editor-1', // Specify container ID
});
// Convert document format
const result = await convertBinToDocument(
binData, // Binary data
fileName, // File name
FILE_TYPE.XLSX, // Target format
media // Media files (optional)
);// Document save data
type SaveDocumentData = {
fileName: string; // File name
fileType: string; // File type (e.g., 'xlsx', 'docx')
binData: Uint8Array; // Binary data
instanceId: string; // Instance ID (used for event matching in multi-instance mode)
media?: Record<string, string>; // Media file mapping
}
// Document ready data
type DocumentReadyData = {
fileName: string; // File name
fileType: string; // File type
}- OnlyOffice SDK: Integrates OnlyOffice official JavaScript SDK, providing core document editing capabilities
- WebAssembly: Uses x2t-wasm module to implement document format conversion functionality
- Client-Side Architecture: All functional modules run in the browser environment without server dependencies
The project is configured for static export and can be deployed directly to Vercel:
# Install dependencies
npm install
# or
pnpm install
# Build project
npm run build
# Vercel will automatically detect and deployAccess URL: https://mvp-onlyoffice.vercel.app/
The project supports static export, and built files can be deployed to any static hosting service:
# Build static files
npm run build
# Output directory: out/
# Can be directly deployed to GitHub Pages, Netlify, Nginx, etc.# Clone repository
git clone <repository-url>
cd mvp-onlyoffice
# Install dependencies
npm install
# or
pnpm install
# Start development server
npm run dev
# Access http://localhost:3001A utility script for compressing files in a folder (excluding WASM files) to reduce bundle size. This script recursively processes directories and compresses JavaScript, HTML, CSS, and other text-based files.
- Multi-format Support: Compresses
.js,.html,.mjs,.cjs,.ts,.jsx,.tsx,.cssfiles - Smart Compression:
- JavaScript/TypeScript: Uses
terserfor minification (without variable name mangling to avoid breaking code) - CSS: Uses
postcss+cssnanofor optimization - HTML: Uses
html-minifier-terserfor minification
- JavaScript/TypeScript: Uses
- Safe Processing: Automatically falls back to copying original files if compression fails
- Detailed Statistics: Provides comprehensive compression statistics including file counts and size reduction percentages
- WASM Files Preserved: Automatically skips WASM files to prevent corruption
# Use default paths (compresses from version 7 to 7-minify)
node scripts/minify.js
# Specify custom source and target directories
node scripts/minify.js <sourceDir> <targetDir>
# Example: Compress files from one directory to another
node scripts/minify.js ./public/packages/onlyoffice/7 ./public/packages/onlyoffice/7-minify- Source Directory:
public/packages/onlyoffice/7 - Target Directory:
public/packages/onlyoffice/7-minify
- JavaScript/TypeScript:
- Removes comments
- Preserves console/debugger statements
- No variable name mangling (safe for OnlyOffice SDK)
- CSS:
- Full CSS optimization via cssnano
- HTML:
- Removes comments
- Collapses whitespace
- Preserves attribute quotes and structure
The script provides real-time progress updates and a final summary including:
- Total files processed
- Number of compressed files
- Number of copied files
- Original total size
- Compressed total size
- Overall size reduction percentage
mvp-onlyoffice/
βββ src/
β βββ app/ # Next.js application pages
β β βββ excel/
β β β βββ base/ # Excel editor page (/excel/base)
β β βββ docs/
β β β βββ base/ # Word editor page (/docs/base)
β β βββ ppt/
β β β βββ base/ # PowerPoint editor page (/ppt/base)
β β βββ multi/
β β β βββ base/ # Multi-instance basic demo page (/multi/base)
β β β βββ tabs/ # Multi-instance Tab demo page (/multi/tabs)
β β βββ page.tsx # Home page (redirects to /excel/base)
β βββ onlyoffice-comp/ # OnlyOffice component library
β β βββ lib/
β β βββ editor-manager.ts # Editor manager (supports multi-instance)
β β βββ x2t.ts # Document conversion module
β β βββ eventbus.ts # Event bus
β β βββ ...
β βββ components/ # Common components
βββ public/ # Static resources
β βββ web-apps/ # OnlyOffice Web application resources
β βββ sdkjs/ # OnlyOffice SDK resources
β βββ wasm/ # WebAssembly converter
βββ onlyoffice-x2t-wasm/ # x2t-wasm source code
/- Home page, automatically redirects to/excel/base/excel/base- Excel spreadsheet editor (single-instance mode)/docs/base- Word document editor (single-instance mode)/ppt/base- PowerPoint presentation editor (single-instance mode)/multi/base- Multi-instance basic demo, showcasing multiple independent editor instances running simultaneously/multi/tabs- Multi-instance Tab demo, showcasing multi-tab editor implementation with LRU cache management
This project complies with open-source licensing requirements and does not include copyrighted commercial font files (such as Arial, Times New Roman, Microsoft YaHei, SimSun, etc.). These font names are still retained in the configuration to ensure document compatibility, but actual font files need to be added by users.
To add fonts, follow these steps:
- Check the
public/sdkjs/common/AllFonts.jsfile - Find the target font's index number in the
__fonts_filesarray - Place the font file in the
public/fonts/directory - Rename the file to the corresponding index number (no extension needed)
Example: Adding Arial Font
- Arial regular font index is
223β Place file aspublic/fonts/223 - Arial bold index is
226β Place file aspublic/fonts/226 - Arial italic index is
224β Place file aspublic/fonts/224 - Arial bold italic index is
225β Place file aspublic/fonts/225
Important Note: Please ensure that the font files used comply with relevant licensing agreements, only use open-source fonts or fonts with proper authorization.
- OnlyOffice API Documentation - OnlyOffice official API reference
- ranuts/document - Reference static resource implementation
- OnlyOffice Web Apps - OnlyOffice web application source code
- OnlyOffice SDK - OnlyOffice JavaScript SDK
- x2t-wasm - WebAssembly document converter
Welcome to submit Issues and Pull Requests to help improve the project!
The project uses an open-source license. For details, please see the LICENSE file.
It is recommended to use modern browsers (latest versions of Chrome, Firefox, Edge, Safari) for the best experience.