yao/excel
Max 57fe05bed8 fix: Update processOpen to use writable flag for Excel file operations
- Change the argument from readonly to writable in the processOpen function.
- Adjust the Open function call to reflect the new writable parameter for improved clarity in file handling.
2025-03-21 21:56:22 +08:00
..
each.go feat: Migrate Excel plugin to built-in functionality 2025-03-21 20:56:35 +08:00
each_test.go feat: Migrate Excel plugin to built-in functionality 2025-03-21 20:56:35 +08:00
excel.go feat: Enhance Excel functionality with row and column operations 2025-03-21 21:39:03 +08:00
excel_test.go feat: Migrate Excel plugin to built-in functionality 2025-03-21 20:56:35 +08:00
process.go fix: Update processOpen to use writable flag for Excel file operations 2025-03-21 21:56:22 +08:00
process_test.go feat: Enhance Excel functionality with row and column operations 2025-03-21 21:39:03 +08:00
README.md fix: Update processOpen to use writable flag for Excel file operations 2025-03-21 21:56:22 +08:00
write.go feat: Migrate Excel plugin to built-in functionality 2025-03-21 20:56:35 +08:00

Yao Excel Module

A Go module for manipulating Excel files with TypeScript API support.

IMPORTANT: Always Close Resources

IMPORTANT: Always make sure to close Excel file handles using excel.close when done to prevent memory leaks and file locking issues. Failing to close handles may cause file corruption or application errors.

Quick Example

Here's a simple but complete example showing proper resource management:

// Open an Excel file
const h = Process("excel.open", "data.xlsx", true);

// Perform operations
const sheets = Process("excel.sheets", h);
Process("excel.write.cell", h, sheets[0], "A1", "Hello World");
Process("excel.save", h);

// IMPORTANT: Always close the handle when done
Process("excel.close", h);

Usage in TypeScript

You can use the Excel module in TypeScript through the Process API. Below are examples of common operations with return type descriptions.

Basic Operations

Open an Excel file

/**
 * Opens an Excel file
 * @param path - Path to the Excel file
 * @param writable - Whether to open in writable mode (true) or read-only mode (false)
 * @returns string - Handle ID used for subsequent operations
 */
const h: string = Process("excel.open", "file.xlsx", true);

// Open in read-only mode (false parameter or not passed)
const hRead: string = Process("excel.open", "file.xlsx", false);
// or simply
const h2: string = Process("excel.open", "file.xlsx");

// IMPORTANT: Don't forget to close the handle when done
// Process("excel.close", h);

Get all sheets in the workbook

/**
 * Gets all sheet names in the workbook
 * @param handle - Handle ID from excel.open
 * @returns string[] - Array of sheet names
 */
const sheets: string[] = Process("excel.sheets", h);
// Example output: ["Sheet1", "Sheet2"]

Close a file

/**
 * Closes an Excel file
 * @param handle - Handle ID from excel.open
 * @returns null
 */
Process("excel.close", h);

Save changes to file

/**
 * Saves changes to the Excel file
 * @param handle - Handle ID from excel.open
 * @returns null
 */
Process("excel.save", h);

Reading Data

Read a cell's value

/**
 * Reads a cell's value
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param cell - Cell reference (e.g. "A1")
 * @returns string - Cell value
 */
const value: string = Process("excel.read.cell", h, "SheetName", "A1");

Read all rows

/**
 * Reads all rows in a sheet
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @returns string[][] - Two-dimensional array of cell values
 */
const rows: string[][] = Process("excel.read.row", h, "SheetName");

Read all columns

/**
 * Reads all columns in a sheet
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @returns string[][] - Two-dimensional array of cell values
 */
const columns: string[][] = Process("excel.read.column", h, "SheetName");

Writing Data

Write to a cell

/**
 * Writes a value to a cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param cell - Cell reference (e.g. "A1")
 * @param value - Value to write (string, number, boolean, etc.)
 * @returns null
 */
Process("excel.write.cell", h, "SheetName", "A1", "Hello World");
// Can write different types of values
Process("excel.write.cell", h, "SheetName", "A2", 123.45);
Process("excel.write.cell", h, "SheetName", "A3", true);

Write a row

/**
 * Writes values to a row starting at the specified cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCell - Starting cell reference (e.g. "A1")
 * @param values - Array of values to write
 * @returns null
 */
Process("excel.write.row", h, "SheetName", "A1", ["Cell1", "Cell2", "Cell3"]);

Write a column

/**
 * Writes values to a column starting at the specified cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCell - Starting cell reference (e.g. "A1")
 * @param values - Array of values to write
 * @returns null
 */
Process("excel.write.column", h, "SheetName", "A1", ["Row1", "Row2", "Row3"]);

Write multiple rows

/**
 * Writes a two-dimensional array of values starting at the specified cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCell - Starting cell reference (e.g. "A1")
 * @param values - Two-dimensional array of values to write
 * @returns null
 */
Process("excel.write.all", h, "SheetName", "A1", [
  ["Row1Cell1", "Row1Cell2", "Row1Cell3"],
  ["Row2Cell1", "Row2Cell2", "Row2Cell3"],
]);

Formatting and Styling

Set cell style

/**
 * Sets a cell's style
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param cell - Cell reference (e.g. "A1")
 * @param styleID - Style ID
 * @returns null
 */
Process("excel.set.style", h, "SheetName", "A1", 1);

Set row height

/**
 * Sets a row's height
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param row - Row number
 * @param height - Height in points
 * @returns null
 */
Process("excel.set.rowheight", h, "SheetName", 1, 30); // Set row 1 to 30 pts height

Set column width

/**
 * Sets column width for a range of columns
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCol - Starting column letter
 * @param endCol - Ending column letter
 * @param width - Width in points
 * @returns null
 */
Process("excel.set.columnwidth", h, "SheetName", "A", "B", 20);

Merge cells

/**
 * Merges cells in a range
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCell - Starting cell reference (e.g. "A1")
 * @param endCell - Ending cell reference (e.g. "B2")
 * @returns null
 */
Process("excel.set.mergecell", h, "SheetName", "A1", "B2");

Unmerge cells

/**
 * Unmerges previously merged cells
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param startCell - Starting cell reference (e.g. "A1")
 * @param endCell - Ending cell reference (e.g. "B2")
 * @returns null
 */
Process("excel.set.unmergecell", h, "SheetName", "A1", "B2");

Set a formula

/**
 * Sets a formula in a cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param cell - Cell reference (e.g. "C1")
 * @param formula - Excel formula without the leading equals sign
 * @returns null
 */
Process("excel.set.formula", h, "SheetName", "C1", "SUM(A1:B1)");
/**
 * Adds a hyperlink to a cell
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @param cell - Cell reference (e.g. "A1")
 * @param url - URL for the hyperlink
 * @param text - Display text for the hyperlink
 * @returns null
 */
Process(
  "excel.set.link",
  h,
  "SheetName",
  "A1",
  "https://example.com",
  "Visit Example"
);

Iterating Through Data

Row Iterator

/**
 * Opens a row iterator
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @returns string - Row iterator ID
 */
const rid: string = Process("excel.each.openrow", h, "SheetName");

/**
 * Gets the next row from the iterator
 * @param rowID - Row iterator ID from excel.each.openrow
 * @returns string[] | null - Array of cell values or null if no more rows
 */
let row: string[] | null;
while ((row = Process("excel.each.nextrow", rid)) !== null) {
  // Process the row
  console.log(row);
}

/**
 * IMPORTANT: Always close the row iterator when done
 * @param rowID - Row iterator ID from excel.each.openrow
 * @returns null
 */
Process("excel.each.closerow", rid);

Column Iterator

/**
 * Opens a column iterator
 * @param handle - Handle ID from excel.open
 * @param sheet - Sheet name
 * @returns string - Column iterator ID
 */
const cid: string = Process("excel.each.opencolumn", h, "SheetName");

/**
 * Gets the next column from the iterator
 * @param colID - Column iterator ID from excel.each.opencolumn
 * @returns string[] | null - Array of cell values or null if no more columns
 */
let col: string[] | null;
while ((col = Process("excel.each.nextcolumn", cid)) !== null) {
  // Process the column
  console.log(col);
}

/**
 * IMPORTANT: Always close the column iterator when done
 * @param colID - Column iterator ID from excel.each.opencolumn
 * @returns null
 */
Process("excel.each.closecolumn", cid);

Utility Functions

Convert between column names and indices

/**
 * Converts a column name to a column number
 * @param colName - Column name (e.g. "A", "AB")
 * @returns number - Column number (1-based)
 */
const colNum: number = Process("excel.convert.columnnametonumber", "AK"); // Returns 37

/**
 * Converts a column number to a column name
 * @param colNum - Column number (1-based)
 * @returns string - Column name
 */
const colName: string = Process("excel.convert.columnnumbertoname", 37); // Returns "AK"

Convert between cell references and coordinates

/**
 * Converts a cell reference to coordinates
 * @param cell - Cell reference (e.g. "A1")
 * @returns number[] - Array with [columnNumber, rowNumber] (1-based)
 */
const coords: number[] = Process("excel.convert.cellnametocoordinates", "A1"); // Returns [1, 1]

/**
 * Converts coordinates to a cell reference
 * @param col - Column number (1-based)
 * @param row - Row number (1-based)
 * @returns string - Cell reference
 */
const cellName: string = Process("excel.convert.coordinatestocellname", 1, 1); // Returns "A1"

Complete Workflow Example

// Open Excel file in writable mode
const h: string = Process("excel.open", "file.xlsx", true);

// Get available sheets
const sheets: string[] = Process("excel.sheets", h);
const sheetName: string = sheets[0];

// Read some data
const value: string = Process("excel.read.cell", h, sheetName, "A1");
console.log("Cell A1 contains:", value);

// Write data
Process("excel.write.cell", h, sheetName, "B1", "New Value");
Process("excel.write.row", h, sheetName, "A2", ["Data1", "Data2", "Data3"]);

// Add a formula
Process("excel.set.formula", h, sheetName, "D1", "SUM(A1:C1)");

// Format cells
Process("excel.set.rowheight", h, sheetName, 1, 30);
Process("excel.set.columnwidth", h, sheetName, "A", "D", 15);

// Save changes
Process("excel.save", h);

// IMPORTANT: Always close the handle when done
Process("excel.close", h);

Notes

  • Always make sure to close open file handles using excel.close when done to prevent resource leaks and file locking issues.
  • Remember to save changes with excel.save before closing to ensure all modifications are persisted.
  • For performance reasons, try to batch operations where possible instead of making many small changes.