Skip to content

🎉 Release v0.5.3

Compare
Choose a tag to compare
@hexf00 hexf00 released this 04 Jan 13:25
· 121 commits to dev since this release

🎊 [email protected]

Univer Banner

🚧 Important Note

This project is still in heavy development, and major API changes are expected. Your feedback is crucial! Please submit issues and suggestions to help us shape the future of Univer.

🚀 Getting Started

If you're eager to explore Univer, check out our getting started documentation.
Dive into the world of collaborative document, spreadsheet, and presentation editing powered by Univer!

📊 Introducing Univer Go Beta!

Important

Univer Go Beta is now available!
We are excited to announce the release of Univer Go, a new desktop application that enables you to build your own spreadsheet and seamlessly integrate with AI agents, databases, and applications.

✨ Fun Built-in Templates

  • AI Spreadsheet Translator: Utilize the Univer API in combination with AI to achieve instant multilingual translation of spreadsheet content
  • Work Calendar: Generate a work calendar with one click, demonstrating how to use the Univer API to load snapshot data, customize formulas, bind cell events, and utilize the permissions module
  • Gantt Chart: Insert any number of Gantt charts into a spreadsheet with a single click, showcasing how to use the Univer API to add formulas, adjust cell styles, merge cells, set conditional formatting, and add data validation
  • High-performance Pivot Tables: Quickly create pivot tables and discover how to use the pivot table API in Univer Go to enhance data analysis efficiency
  • Tic Tac Toe: Share a link to play Tic-Tac-Toe with friends, learn how to bind Canvas events and implement real-time multiplayer interactions

More templates are waiting for you to explore. Feel free to share your templates with us!

Beta version is now available for both Windows. We welcome community members to test it out and share their feedback to help us improve the platform!

📊 Univer Sheets

🎉 Highlights

In this release, we are excited to introduce a new set of features and improvements to enhance your Univer experience. Here are the highlights:

  • Optimized Facade API chaining, enabling more fluent API calls. This update may require adjustments to existing code, please refer to the Breaking Changes section #4329 #4403 #4412
import '@univerjs/sheets/facade'

univerAPI.getActiveWorkbook().insertSheet()
    // set basic properties
    .setName('Sales Report 2024')
    // set freeze pane
    .setFrozenRows(2)
    .setFrozenColumns(1)
    // set column width
    .setColumnWidths(0, 1, 180)  // product name column
    .setColumnWidths(1, 1, 120)  // price column
    .setColumnWidths(2, 1, 100)  // quantity column
    .setColumnWidths(3, 1, 120)  // total price column
    .setColumnWidths(4, 1, 150)  // note column
    // set row height
    .setRowHeight(0, 35)  // main header
    .setRowHeight(1, 30)  // sub header
    // set values
    .getRange("a1:e1")
    .setValues([
        ["product name", "price", "quantity", "total price", "note"],
    ])
import '@univerjs/sheets/facade'
univerAPI.getActiveWorkbook().getActiveSheet().getRange("a1:c5").useThemeStyle('default')
univerAPI.getActiveWorkbook().getActiveSheet().getRange("a1:c5").useThemeStyle(null)

image

  • Added Facade API FRange.splitTextToColumns for splitting text into columns
import '@univerjs/sheets/facade'
univerAPI.getActiveWorkbook().getActiveSheet().getRange("a1").setValue("1;2;3").splitTextToColumns()
  • Added Facade API FFormula.registerFunction and FFormula.registerAsyncFunction for creating custom functions #4399
import '@univerjs/sheets/facade'
import '@univerjs/sheets/sheets-formula'
univerAPI.getFormula().registerFunction('HELLO', (name) => `Hello, ${name}!`, 'A simple greeting function');
// Use the function in a cell
univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1').setValue('World');
univerAPI.getActiveWorkbook().getActiveSheet().getRange('A2').setValue({ f: '=HELLO(A1)' });
// A2 will display: "Hello, World!"

🐞 Bug Fixes

  • Fixed mouse scrollbar operation issues #4396
  • Fixed non-responsive dropdown menu clicks in the More menu #4416
  • Fixed known issues

💔 Breaking Changes

  • Tools.deepMerge is deprecated, please use merge instead

Before:

import { Tools } from '@univerjs/core'
Tools.deepMerge(obj1, obj2)

After:

import { merge } from '@univerjs/core'
merge(obj1, obj2)
  • Changed return type of chained Facade API calls from Promise<boolean> to FUniver or FWorkbook or FWorksheet or FRange or FDataValidation or FFilter #4329 #4403 #4412

Before:

await univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1:A5').setValue('123');
await univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1:A5').merge()

After:

univerAPI.getActiveWorkbook().getActiveSheet().getRange('A1:A5').setValue('123').merge();
FUniver{
...
-setCrosshairHighlightColor(color: string): void;
+setCrosshairHighlightColor(color: string): FUniver;
-setCrosshairHighlightEnabled(enabled: boolean): void;
+setCrosshairHighlightEnabled(enabled: boolean): FUniver;
-showMessage(options: IMessageProps): void;
+showMessage(options: IMessageProps): FUniver;
-addWatermark(type: IWatermarkTypeEnum.Text, config: ITextWatermarkConfig): void;
+addWatermark(type: IWatermarkTypeEnum.Text, config: ITextWatermarkConfig): FUniver;
-addWatermark(type: IWatermarkTypeEnum.Image, config: IImageWatermarkConfig): void;
+addWatermark(type: IWatermarkTypeEnum.Image, config: IImageWatermarkConfig): FUniver;
-deleteWatermark(): void;
+deleteWatermark(): FUniver;
...
}
FWorkbook{
...

-deleteActiveSheet(): Promise<boolean>;
+deleteActiveSheet(): FWorkbook;
-deleteSheet(sheet: FWorksheet): Promise<boolean>;
+deleteSheet(sheet: FWorksheet): FWorkbook;
-duplicateActiveSheet(): Promise<boolean>;
+duplicateActiveSheet(): FWorkbook;
-duplicateSheet(sheet: FWorksheet): Promise<boolean>;
+duplicateSheet(sheet: FWorksheet): FWorkbook;
-moveActiveSheet(index: number): Promise<boolean>;
+moveActiveSheet(index: number): FWorkbook;
-moveSheet(sheet: FWorksheet, index: number): Promise<boolean>;
+moveSheet(sheet: FWorksheet, index: number): FWorkbook;
-redo(): Promise<boolean>;
+redo(): FWorkbook;
-undo(): Promise<boolean>;
+undo(): FWorkbook;
...
}
FWorksheet {
...
-cancelFreeze(): boolean;
+cancelFreeze(): FWorksheet;
-clear(options?: IFacadeClearOptions): Promise<boolean>;
+clear(options?: IFacadeClearOptions): FWorksheet;
-clearContents(): Promise<boolean>;
+clearContents(): FWorksheet;
-clearFormats(): Promise<boolean>;
+clearFormats(): FWorksheet;
-deleteColumn(columnPosition: number): Promise<FWorksheet>;
+deleteColumn(columnPosition: number): FWorksheet;
-deleteColumns(columnPosition: number, howMany: number): Promise<FWorksheet>;
+deleteColumns(columnPosition: number, howMany: number): FWorksheet;
-deleteRow(rowPosition: number): Promise<FWorksheet>;
+deleteRow(rowPosition: number): FWorksheet;
-deleteRows(rowPosition: number, howMany: number): Promise<FWorksheet>;
+deleteRows(rowPosition: number, howMany: number): FWorksheet;
-hideColumn(column: FRange): Promise<FWorksheet>;
+hideColumn(column: FRange): FWorksheet;
-hideColumns(columnIndex: number, numColumns?: number): Promise<FWorksheet>;
+hideColumns(columnIndex: number, numColumns?: number): FWorksheet;
-hideRow(row: FRange): Promise<FWorksheet>;
+hideRow(row: FRange): FWorksheet;
-hideRows(rowIndex: number, numRows?: number): Promise<FWorksheet>;
+hideRows(rowIndex: number, numRows?: number): FWorksheet;
-hideSheet(): void;
+hideSheet(): FWorksheet;
-insertColumnAfter(afterPosition: number): Promise<FWorksheet>;
+insertColumnAfter(afterPosition: number): FWorksheet;
-insertColumnBefore(beforePosition: number): Promise<FWorksheet>;
+insertColumnBefore(beforePosition: number): FWorksheet;
-insertColumns(columnIndex: number, numColumns?: number): Promise<FWorksheet>;
+insertColumns(columnIndex: number, numColumns?: number): FWorksheet;
-insertColumnsAfter(afterPosition: number, howMany: number): Promise<FWorksheet>;
+insertColumnsAfter(afterPosition: number, howMany: number): FWorksheet;
-insertColumnsBefore(beforePosition: number, howMany: number): Promise<FWorksheet>;
+insertColumnsBefore(beforePosition: number, howMany: number): FWorksheet;
-insertRowAfter(afterPosition: number): Promise<FWorksheet>;
+insertRowAfter(afterPosition: number): FWorksheet;
-insertRowBefore(beforePosition: number): Promise<FWorksheet>;
+insertRowBefore(beforePosition: number): FWorksheet;
-insertRows(rowIndex: number, numRows?: number): Promise<FWorksheet>;
+insertRows(rowIndex: number, numRows?: number): FWorksheet;
-insertRowsAfter(afterPosition: number, howMany: number): Promise<FWorksheet>;
+insertRowsAfter(afterPosition: number, howMany: number): FWorksheet;
-insertRowsBefore(beforePosition: number, howMany: number): Promise<FWorksheet>;
+insertRowsBefore(beforePosition: number, howMany: number): FWorksheet;
-moveColumns(columnSpec: FRange, destinationIndex: number): Promise<FWorksheet>;
+moveColumns(columnSpec: FRange, destinationIndex: number): FWorksheet;
-moveRows(rowSpec: FRange, destinationIndex: number): Promise<FWorksheet>;
+moveRows(rowSpec: FRange, destinationIndex: number): FWorksheet;
-setColumnCustom(custom: IObjectArrayPrimitiveType<CustomData>): Promise<FWorksheet>;
+setColumnCustom(custom: IObjectArrayPrimitiveType<CustomData>): FWorksheet;
-setColumnDefaultStyle(index: number, style: string | Nullable<IStyleData>): Promise<FWorksheet>;
+setColumnDefaultStyle(index: number, style: string | Nullable<IStyleData>): FWorksheet;
-setColumnWidth(columnPosition: number, width: number): Promise<FWorksheet>;
+setColumnWidth(columnPosition: number, width: number): FWorksheet;
-setColumnWidths(startColumn: number, numColumns: number, width: number): Promise<FWorksheet>;
+setColumnWidths(startColumn: number, numColumns: number, width: number): FWorksheet;
-setDefaultStyle(style: string): Promise<FWorksheet>;
+setDefaultStyle(style: string): FWorksheet;
-setFreeze(freeze: IFreeze): boolean;
+setFreeze(freeze: IFreeze): FWorksheet;
-setFrozenColumns(startColumn: number, endColumn: number): void;
+setFrozenColumns(startColumn: number, endColumn: number): FWorksheet;
-setFrozenRows(startColumn: number, endColumn: number): void;
+setFrozenRows(startColumn: number, endColumn: number): FWorksheet;
-setGridLinesColor(color: string | undefined): Promise<boolean>;
+setGridLinesColor(color: string | undefined): FWorksheet;
-setHiddenGridlines(hidden: boolean): Promise<boolean>;
+setHiddenGridlines(hidden: boolean): FWorksheet;
-setName(name: string): Promise<boolean>;
+setName(name: string): FWorksheet;
-setRowCustom(custom: IObjectArrayPrimitiveType<CustomData>): Promise<FWorksheet>;
+setRowCustom(custom: IObjectArrayPrimitiveType<CustomData>): FWorksheet;
-setRowDefaultStyle(index: number, style: string | Nullable<IStyleData>): Promise<FWorksheet>;
+setRowDefaultStyle(index: number, style: string | Nullable<IStyleData>): FWorksheet;
-setRowHeight(rowPosition: number, height: number): Promise<FWorksheet>;
+setRowHeight(rowPosition: number, height: number): FWorksheet;
-setRowHeights(startRow: number, numRows: number, height: number): Promise<FWorksheet>;
+setRowHeights(startRow: number, numRows: number, height: number): FWorksheet;
-setRowHeightsForced(startRow: number, numRows: number, height: number): Promise<FWorksheet>;
+setRowHeightsForced(startRow: number, numRows: number, height: number): FWorksheet;
-setTabColor(color: string): Promise<boolean>;
+setTabColor(color: string): FWorksheet;
-showColumns(columnIndex: number, numColumns?: number): Promise<FWorksheet>;
+showColumns(columnIndex: number, numColumns?: number): FWorksheet;
-showRows(rowIndex: number, numRows?: number): Promise<FWorksheet>;
+showRows(rowIndex: number, numRows?: number): FWorksheet;
-showSheet(): Promise<boolean>;
+showSheet(): FWorksheet;
-unhideColumn(column: FRange): Promise<FWorksheet>;
+unhideColumn(column: FRange): FWorksheet;
-unhideRow(row: FRange): Promise<FWorksheet>;
+unhideRow(row: FRange): FWorksheet;


-addConditionalFormattingRule(rule: IConditionFormattingRule): Promise<boolean>;
+addConditionalFormattingRule(rule: IConditionFormattingRule): FWorksheet;
-deleteConditionalFormattingRule(cfId: string): Promise<boolean>;
+deleteConditionalFormattingRule(cfId: string): FWorksheet;
-moveConditionalFormattingRule(cfId: string, toCfId: string, type?: IAnchor['type']): Promise<boolean>;
+moveConditionalFormattingRule(cfId: string, toCfId: string, type?: IAnchor['type']): FWorksheet;
-setConditionalFormattingRule(cfId: string, rule: IConditionFormattingRule): Promise<boolean>;
+setConditionalFormattingRule(cfId: string, rule: IConditionFormattingRule): FWorksheet;
-zoom(zoomRatio: number): FWorksheet;
+zoom(zoomRatio: number): FWorksheet;
...
}
FRange {
...
-merge(defaultMerge?: boolean): Promise<FRange>;
+merge(defaultMerge?: boolean): FRange;
-mergeAcross(defaultMerge?: boolean): Promise<FRange>;
+mergeAcross(defaultMerge?: boolean): FRange;
-mergeVertically(defaultMerge?: boolean): Promise<FRange>;
+mergeVertically(defaultMerge?: boolean): FRange;
-setHorizontalAlignment(alignment: FHorizontalAlignment): Promise<boolean>;
+setHorizontalAlignment(alignment: FHorizontalAlignment): FRange;
-setValue(value: CellValue | ICellData): Promise<boolean>;
+setValue(value: CellValue | ICellData): FRange;
-setValues(value: CellValue[][] | IObjectMatrixPrimitiveType<CellValue> | ICellData[][] | IObjectMatrixPrimitiveType<ICellData>): Promise<boolean>;
+setValues(value: CellValue[][] | IObjectMatrixPrimitiveType<CellValue> | ICellData[][] | IObjectMatrixPrimitiveType<ICellData>): FRange;
-setVerticalAlignment(alignment: FVerticalAlignment): Promise<boolean>;
+setVerticalAlignment(alignment: FVerticalAlignment): FRange;
-setWrap(isWrapEnabled: boolean): Promise<boolean>;
+setWrap(isWrapEnabled: boolean): FRange;
-setWrapStrategy(strategy: WrapStrategy): Promise<boolean>;
+setWrapStrategy(strategy: WrapStrategy): FRange;

-addConditionalFormattingRule(rule: IConditionFormattingRule): Promise<boolean>;
+addConditionalFormattingRule(rule: IConditionFormattingRule): FRange;
-deleteConditionalFormattingRule(cfId: string): Promise<boolean>;
+deleteConditionalFormattingRule(cfId: string): FRange;
-moveConditionalFormattingRule(cfId: string, toCfId: string, type?: IAnchor['type']): Promise<boolean>;
+moveConditionalFormattingRule(cfId: string, toCfId: string, type?: IAnchor['type']): FRange;
-setConditionalFormattingRule(cfId: string, rule: IConditionFormattingRule): Promise<boolean>;
+setConditionalFormattingRule(cfId: string, rule: IConditionFormattingRule): FRange;
-setDataValidation(rule: Nullable<FDataValidation>): Promise<FRange>;
+setDataValidation(rule: Nullable<FDataValidation>): FRange;
-createFilter(): Promise<FFilter | null>;
+createFilter(): FRange;
-cancelHyperLink(id: string): Promise<boolean>;
+cancelHyperLink(id: string): boolean;
-setNumberFormat(pattern: string): Promise<boolean>;
+setNumberFormat(pattern: string): FRange;
-sort(column: SortColumnSpec | SortColumnSpec[]): Promise<FRange>;
+sort(column: SortColumnSpec | SortColumnSpec[]): FRange;
...
}
FDataValidation{
-setCriteria(type: DataValidationType, values: [DataValidationOperator, string, string]): boolean;
+setCriteria(type: DataValidationType, values: [DataValidationOperator, string, string]): FDataValidation;
-setOptions(options: Partial<IDataValidationRuleOptions>): boolean;
+setOptions(options: Partial<IDataValidationRuleOptions>): FDataValidation;
-setRanges(ranges: FRange[]): boolean;
+setRanges(ranges: FRange[]): FDataValidation;
}
FFilter{
-remove(): Promise<boolean>;
+remove(): FFilter;
-removeColumnFilterCriteria(col: number): Promise<boolean>;
+removeColumnFilterCriteria(col: number): FFilter;
-removeFilterCriteria(): Promise<boolean>;
+removeFilterCriteria(): FFilter;
-setColumnFilterCriteria(col: number, criteria: ISetSheetsFilterCriteriaCommandParams['criteria']): Promise<boolean>;
+setColumnFilterCriteria(col: number, criteria: ISetSheetsFilterCriteriaCommandParams['criteria']): FFilter;
}

📢 0.6.0 Preview

Important

The development of version 0.6.0 is currently underway. Starting with this release, Univer will support integration with projects using React@19 . However, this update may introduce breaking changes for users relying on React@16 or Univer UMD builds.
If you have any questions or concerns, please feel free to share your suggestions and feedback via GitHub Issues.

  • Future versions will continue to improve enums and events, optimizing the Facade API experience #4346 #4406
    • FUniver.Enum
    • FUniver.Event
    • FUniver.addEvent(FUniver.Event.xxx, ()=> { })

📝 Univer Docs

  • Fixed known issues

🌐 Univer Server

  • Fixed known issues

📦 Univer Presets

  • Updated to the latest version of Univer

📢 Join the Conversation

We welcome your input and insights as we embark on this exciting journey. Connect with us on:

📝 Changelog

Full changelog (2025-01-04)

Bug Fixes

Features

Reverts

  • get fontExtension from cache, revert to worksheet.getCell (#4417) (5c03dff)