mirror of
https://github.com/canna71/obsidian-sheets.git
synced 2026-07-22 04:47:23 +00:00
basic
This commit is contained in:
parent
7bb91b9856
commit
f8147bc696
6 changed files with 316 additions and 198 deletions
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
export interface SheetjsSettings {
|
||||
addRibbonIcon: boolean;
|
||||
|
||||
enableSaveToFile: boolean
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: SheetjsSettings = {
|
||||
addRibbonIcon: true,
|
||||
|
||||
addRibbonIcon: false,
|
||||
enableSaveToFile: true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,41 +5,21 @@
|
|||
import {
|
||||
MarkdownPostProcessorContext,
|
||||
MarkdownView,
|
||||
debounce,
|
||||
parseYaml,
|
||||
stringifyYaml,
|
||||
Notice,
|
||||
} from "obsidian";
|
||||
import { SheetjsSettings } from "src/Settings";
|
||||
import Spreadsheet from "x-data-spreadsheet";
|
||||
// import "x-data-spreadsheet/dist/xspreadsheet.css";
|
||||
// import * as fs from "fs/promises"
|
||||
// import * as path from "path"
|
||||
|
||||
import * as XLSX from "xlsx";
|
||||
import * as ExcelJS from "exceljs";
|
||||
import { stox, xtos } from "../utils/xlsxpread";
|
||||
import { stox } from "../utils/xlsxpread";
|
||||
import { toSpreadsheet } from "src/utils/excelConverter";
|
||||
import { createSpreadSheet, saveToFile } from "./spreadSheetWrapper";
|
||||
|
||||
const saveIcon =
|
||||
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc3MTc3MDkyOTg4IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI2NzgiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTIxMy4zMzMzMzMgMTI4aDU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMgODUuMzMzMzMzdjU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMgODUuMzMzMzMzSDIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMtODUuMzMzMzMzVjIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMtODUuMzMzMzMzeiBtMzY2LjkzMzMzNCAxMjhoMzQuMTMzMzMzYTI1LjYgMjUuNiAwIDAgMSAyNS42IDI1LjZ2MTE5LjQ2NjY2N2EyNS42IDI1LjYgMCAwIDEtMjUuNiAyNS42aC0zNC4xMzMzMzNhMjUuNiAyNS42IDAgMCAxLTI1LjYtMjUuNlYyODEuNmEyNS42IDI1LjYgMCAwIDEgMjUuNi0yNS42ek0yMTMuMzMzMzMzIDIxMy4zMzMzMzN2NTk3LjMzMzMzNGg1OTcuMzMzMzM0VjIxMy4zMzMzMzNIMjEzLjMzMzMzM3ogbTEyOCAwdjI1NmgzNDEuMzMzMzM0VjIxMy4zMzMzMzNoODUuMzMzMzMzdjI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjcgNDIuNjY2NjY3SDI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjctNDIuNjY2NjY3VjIxMy4zMzMzMzNoODUuMzMzMzMzek0yNTYgMjEzLjMzMzMzM2g4NS4zMzMzMzMtODUuMzMzMzMzeiBtNDI2LjY2NjY2NyAwaDg1LjMzMzMzMy04NS4zMzMzMzN6IG0wIDU5Ny4zMzMzMzR2LTEyOEgzNDEuMzMzMzMzdjEyOEgyNTZ2LTE3MC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjctNDIuNjY2NjY3aDQyNi42NjY2NjZhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjcgNDIuNjY2NjY3djE3MC42NjY2NjdoLTg1LjMzMzMzM3ogbTg1LjMzMzMzMyAwaC04NS4zMzMzMzMgODUuMzMzMzMzek0zNDEuMzMzMzMzIDgxMC42NjY2NjdIMjU2aDg1LjMzMzMzM3oiIHAtaWQ9IjI2NzkiIGZpbGw9IiMyYzJjMmMiPjwvcGF0aD48L3N2Zz4=";
|
||||
|
||||
function resolve_book_type(fileName: string): XLSX.BookType {
|
||||
const _BT: any = {
|
||||
xls: "biff8",
|
||||
htm: "html",
|
||||
slk: "sylk",
|
||||
socialcalc: "eth",
|
||||
Sh33tJS: "WTF",
|
||||
};
|
||||
let bookType = "xlsx";
|
||||
const ext = fileName.slice(fileName.lastIndexOf(".")).toLowerCase();
|
||||
if (ext.match(/^\.[a-z]+$/)) {
|
||||
bookType = ext.slice(1);
|
||||
}
|
||||
bookType = _BT[bookType] || bookType;
|
||||
return bookType as XLSX.BookType;
|
||||
}
|
||||
|
||||
const DEFAULT_OPTIONS = {
|
||||
height: 540,
|
||||
|
|
@ -51,10 +31,9 @@ const DEFAULT_OPTIONS = {
|
|||
cellWidth: 100,
|
||||
};
|
||||
|
||||
interface SheetOptions {
|
||||
filename?: string;
|
||||
data?: any;
|
||||
}
|
||||
const saveIcon =
|
||||
"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBzdGFuZGFsb25lPSJubyI/PjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+PHN2ZyB0PSIxNTc3MTc3MDkyOTg4IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjI2NzgiIHdpZHRoPSIxOCIgaGVpZ2h0PSIxOCIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxkZWZzPjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+PC9zdHlsZT48L2RlZnM+PHBhdGggZD0iTTIxMy4zMzMzMzMgMTI4aDU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMgODUuMzMzMzMzdjU5Ny4zMzMzMzRhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMgODUuMzMzMzMzSDIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMS04NS4zMzMzMzMtODUuMzMzMzMzVjIxMy4zMzMzMzNhODUuMzMzMzMzIDg1LjMzMzMzMyAwIDAgMSA4NS4zMzMzMzMtODUuMzMzMzMzeiBtMzY2LjkzMzMzNCAxMjhoMzQuMTMzMzMzYTI1LjYgMjUuNiAwIDAgMSAyNS42IDI1LjZ2MTE5LjQ2NjY2N2EyNS42IDI1LjYgMCAwIDEtMjUuNiAyNS42aC0zNC4xMzMzMzNhMjUuNiAyNS42IDAgMCAxLTI1LjYtMjUuNlYyODEuNmEyNS42IDI1LjYgMCAwIDEgMjUuNi0yNS42ek0yMTMuMzMzMzMzIDIxMy4zMzMzMzN2NTk3LjMzMzMzNGg1OTcuMzMzMzM0VjIxMy4zMzMzMzNIMjEzLjMzMzMzM3ogbTEyOCAwdjI1NmgzNDEuMzMzMzM0VjIxMy4zMzMzMzNoODUuMzMzMzMzdjI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjcgNDIuNjY2NjY3SDI5OC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMS00Mi42NjY2NjctNDIuNjY2NjY3VjIxMy4zMzMzMzNoODUuMzMzMzMzek0yNTYgMjEzLjMzMzMzM2g4NS4zMzMzMzMtODUuMzMzMzMzeiBtNDI2LjY2NjY2NyAwaDg1LjMzMzMzMy04NS4zMzMzMzN6IG0wIDU5Ny4zMzMzMzR2LTEyOEgzNDEuMzMzMzMzdjEyOEgyNTZ2LTE3MC42NjY2NjdhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjctNDIuNjY2NjY3aDQyNi42NjY2NjZhNDIuNjY2NjY3IDQyLjY2NjY2NyAwIDAgMSA0Mi42NjY2NjcgNDIuNjY2NjY3djE3MC42NjY2NjdoLTg1LjMzMzMzM3ogbTg1LjMzMzMzMyAwaC04NS4zMzMzMzMgODUuMzMzMzMzek0zNDEuMzMzMzMzIDgxMC42NjY2NjdIMjU2aDg1LjMzMzMzM3oiIHAtaWQ9IjI2NzkiIGZpbGw9IiMyYzJjMmMiPjwvcGF0aD48L3N2Zz4=";
|
||||
|
||||
|
||||
export function processCodeBlock(
|
||||
source: string,
|
||||
|
|
@ -78,7 +57,7 @@ export function processCodeBlock(
|
|||
if ((ctx as any).spreadsheet) return;
|
||||
|
||||
const options = { ...DEFAULT_OPTIONS, ...parseYaml(source) };
|
||||
|
||||
|
||||
const {
|
||||
filename,
|
||||
height,
|
||||
|
|
@ -143,39 +122,40 @@ export function processCodeBlock(
|
|||
// }
|
||||
};
|
||||
|
||||
if (!filename) {
|
||||
if (!filename || settings.enableSaveToFile) {
|
||||
spreadsheet_options.extendToolbar = {
|
||||
left: [
|
||||
{
|
||||
tip: "Save",
|
||||
icon: saveIcon,
|
||||
shortcut: "Ctrl+S",
|
||||
onClick: (s: any, d: any) => saveDataIntoBlock(s, d, ctx),
|
||||
onClick: (s: any, d: any) => {
|
||||
if(!filename) saveDataIntoBlock(s, d, ctx);
|
||||
else {
|
||||
saveToFile((ctx as any).spreadsheet, filename)
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
if (filename) {
|
||||
if (filename !== undefined) {
|
||||
(async () => {
|
||||
const fileContent = await app.vault.adapter.readBinary(filename);
|
||||
|
||||
const xlsx = XLSX.read(fileContent, {
|
||||
cellStyles: true,
|
||||
sheetStubs: true, // >
|
||||
});
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
|
||||
const excelWorkbook = await workbook.xlsx.load(fileContent);
|
||||
|
||||
const data2 = toSpreadsheet(excelWorkbook);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const data = stox(xlsx);
|
||||
let data = undefined
|
||||
try {
|
||||
const fileContent = await app.vault.adapter.readBinary(filename);
|
||||
|
||||
data = await parseFileContent(filename, fileContent);
|
||||
} catch (e) {
|
||||
console.warn(e)
|
||||
}
|
||||
|
||||
|
||||
(ctx as any).spreadsheet = createSpreadSheet(
|
||||
container,
|
||||
spreadsheet_options,
|
||||
{ ...options, data: data2 },
|
||||
{ ...options, data: data },
|
||||
ctx
|
||||
);
|
||||
// .loadData();
|
||||
|
|
@ -199,6 +179,26 @@ export function processCodeBlock(
|
|||
// https://github.com/wolf-table/table
|
||||
}
|
||||
|
||||
async function parseFileContent(filename:string, fileContent:ArrayBuffer){
|
||||
|
||||
const ext = filename.slice(filename.lastIndexOf(".")).toLowerCase();
|
||||
if(ext === ".xlsx" || ext === ".csv") {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
const excelWorkbook = await workbook.xlsx.load(fileContent);
|
||||
const data2 = toSpreadsheet(excelWorkbook);
|
||||
return data2;
|
||||
} else {
|
||||
const xlsx = XLSX.read(fileContent, {
|
||||
cellStyles: true,
|
||||
sheetStubs: true, // >
|
||||
});
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const data = stox(xlsx);
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function saveDataIntoBlock(
|
||||
data: any,
|
||||
sheet: any,
|
||||
|
|
@ -224,85 +224,8 @@ function saveDataIntoBlock(
|
|||
}
|
||||
} else {
|
||||
// preview
|
||||
new Notice("Sheet not saved while in read mode");
|
||||
new Notice("Sheet not saved while in reading mode");
|
||||
}
|
||||
}
|
||||
|
||||
function createSpreadSheet(
|
||||
container: HTMLElement,
|
||||
spreadsheet_options: any,
|
||||
options: SheetOptions,
|
||||
ctx: MarkdownPostProcessorContext
|
||||
) {
|
||||
const spreadSheet = new Spreadsheet(
|
||||
container,
|
||||
spreadsheet_options
|
||||
).loadData(options.data || {});
|
||||
spreadSheet.change(
|
||||
debounce((data) => {
|
||||
// save data
|
||||
// console.log(data)
|
||||
if (options.filename) {
|
||||
const spreadsheetData = spreadSheet.getData() as any[];
|
||||
const wb = xtos(spreadsheetData) as XLSX.WorkBook;
|
||||
applyStyles(spreadsheetData, wb);
|
||||
const bookType = resolve_book_type(options.filename);
|
||||
const bytes = XLSX.write(wb, {
|
||||
bookType: bookType,
|
||||
type: "buffer",
|
||||
compression: true,
|
||||
bookSST: true,
|
||||
cellStyles: true,
|
||||
});
|
||||
// fs.writeFile(filename,bytes);
|
||||
app.vault.adapter.writeBinary(options.filename, bytes);
|
||||
console.log(`data saved tp ${options.filename}`);
|
||||
} else {
|
||||
// tentative
|
||||
// saveDataIntoBlock(null,null,ctx)
|
||||
}
|
||||
|
||||
// XLSX.writeFile(xtos(s.getData(data)) as any, filename);
|
||||
}, 1000)
|
||||
);
|
||||
|
||||
return spreadSheet;
|
||||
}
|
||||
|
||||
function applyStyles(ssdata: any, wb: XLSX.WorkBook) {
|
||||
console.log(ssdata, wb);
|
||||
for (const sheet of ssdata) {
|
||||
const { name, styles, rows } = sheet;
|
||||
for (const rowId in rows) {
|
||||
const cells = rows[rowId]["cells"];
|
||||
for (const cellId in cells) {
|
||||
const cell = cells[cellId];
|
||||
if (cell.style !== undefined) {
|
||||
const wbStyle = styleSS2WB(styles[cell.style]);
|
||||
//TODO: apply to the right WB cell
|
||||
const cellRef = XLSX.utils.encode_cell({
|
||||
r: Number(rowId),
|
||||
c: Number(cellId),
|
||||
});
|
||||
wb.Sheets[name][cellRef].s = wbStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function styleSS2WB(ssstyle: any) {
|
||||
const style: any = { patternType: "solid" };
|
||||
if (ssstyle.bgcolor) {
|
||||
style.bgColor = {
|
||||
rgb: ssstyle.bgcolor.substring(1),
|
||||
};
|
||||
}
|
||||
|
||||
if (ssstyle.color) {
|
||||
style.fgColor = {
|
||||
rgb: ssstyle.color.substring(1),
|
||||
};
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
|
|
|||
131
src/Views/spreadSheetWrapper.ts
Normal file
131
src/Views/spreadSheetWrapper.ts
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { MarkdownPostProcessorContext, debounce } from "obsidian";
|
||||
import Spreadsheet from "x-data-spreadsheet";
|
||||
import * as XLSX from "xlsx";
|
||||
import { xtos } from "../utils/xlsxpread";
|
||||
import { toExcelJS } from "src/utils/excelConverter";
|
||||
|
||||
|
||||
function resolve_book_type(fileName: string): XLSX.BookType {
|
||||
const _BT: any = {
|
||||
xls: "biff8",
|
||||
htm: "html",
|
||||
slk: "sylk",
|
||||
socialcalc: "eth",
|
||||
Sh33tJS: "WTF",
|
||||
};
|
||||
let bookType = "xlsx";
|
||||
const ext = fileName.slice(fileName.lastIndexOf(".")).toLowerCase();
|
||||
if (ext.match(/^\.[a-z]+$/)) {
|
||||
bookType = ext.slice(1);
|
||||
}
|
||||
bookType = _BT[bookType] || bookType;
|
||||
return bookType as XLSX.BookType;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function applyStyles(ssdata: any, wb: XLSX.WorkBook) {
|
||||
console.log(ssdata, wb);
|
||||
for (const sheet of ssdata) {
|
||||
const { name, styles, rows } = sheet;
|
||||
for (const rowId in rows) {
|
||||
const cells = rows[rowId]["cells"];
|
||||
for (const cellId in cells) {
|
||||
const cell = cells[cellId];
|
||||
if (cell.style !== undefined) {
|
||||
const wbStyle = styleSS2WB(styles[cell.style]);
|
||||
//TODO: apply to the right WB cell
|
||||
const cellRef = XLSX.utils.encode_cell({
|
||||
r: Number(rowId),
|
||||
c: Number(cellId),
|
||||
});
|
||||
wb.Sheets[name][cellRef].s = wbStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export interface SheetOptions {
|
||||
filename?: string;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export function createSpreadSheet(
|
||||
container: HTMLElement,
|
||||
spreadsheet_options: any,
|
||||
options: SheetOptions,
|
||||
ctx: MarkdownPostProcessorContext
|
||||
) {
|
||||
const spreadSheet = new Spreadsheet(
|
||||
container,
|
||||
spreadsheet_options
|
||||
).loadData(options.data || {});
|
||||
spreadSheet.change(
|
||||
debounce((_data) => {
|
||||
// save data
|
||||
// console.log(data)
|
||||
if (options.filename) {
|
||||
saveToFile(spreadSheet, options.filename);
|
||||
} else {
|
||||
// at the moment we avoid since this would cause re-rendering
|
||||
// saveDataIntoBlock(null,null,ctx)
|
||||
}
|
||||
|
||||
// XLSX.writeFile(xtos(s.getData(data)) as any, filename);
|
||||
}, 1000)
|
||||
);
|
||||
|
||||
return spreadSheet;
|
||||
}
|
||||
|
||||
export async function saveToFile(spreadSheet: Spreadsheet, filename: string) {
|
||||
|
||||
const spreadsheetData = spreadSheet.getData() as any[];
|
||||
const bookType = resolve_book_type(filename);
|
||||
if(bookType === 'xlsx' || bookType === 'csv'){
|
||||
const workbook = toExcelJS(spreadsheetData);
|
||||
const buffer = await workbook.xlsx.writeBuffer();
|
||||
app.vault.adapter.writeBinary(filename, buffer);
|
||||
console.log(`data saved tp ${filename}`);
|
||||
} else {
|
||||
const wb = xtos(spreadsheetData) as XLSX.WorkBook;
|
||||
// applyStyles(spreadsheetData, wb);
|
||||
const bytes = XLSX.write(wb, {
|
||||
bookType: bookType,
|
||||
type: "buffer",
|
||||
compression: true,
|
||||
bookSST: true,
|
||||
cellStyles: true,
|
||||
});
|
||||
app.vault.adapter.writeBinary(filename, bytes);
|
||||
console.log(`data saved tp ${filename}`);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// fs.writeFile(filename,bytes);
|
||||
|
||||
}
|
||||
|
||||
function styleSS2WB(ssstyle: any) {
|
||||
const style: any = { patternType: "solid" };
|
||||
if (ssstyle.bgcolor) {
|
||||
style.bgColor = {
|
||||
rgb: ssstyle.bgcolor.substring(1),
|
||||
};
|
||||
}
|
||||
|
||||
if (ssstyle.color) {
|
||||
style.fgColor = {
|
||||
rgb: ssstyle.color.substring(1),
|
||||
};
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
|
@ -1,72 +1,78 @@
|
|||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
import { Borders, Workbook } from "exceljs";
|
||||
import { Borders, Column, Workbook } from "exceljs";
|
||||
import { convertThemeColorToRGB, rgbToHex } from "./excelColors";
|
||||
import { CellData, CellStyle, RowData, SheetData } from "x-data-spreadsheet";
|
||||
// import { SpreadsheetData } from "x-data-spreadsheet";
|
||||
|
||||
declare module "x-data-spreadsheet" {
|
||||
interface RowData {
|
||||
height?: number;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
type borderDir = "top"|"bottom"|"left"|"right";
|
||||
type borderDir = "top" | "bottom" | "left" | "right";
|
||||
|
||||
export function toSpreadsheet(wb: Workbook) {
|
||||
|
||||
function mapColor(oStyle: CellStyle,border: Partial<Borders>, what: borderDir){
|
||||
if(border[what] && border[what].style && oStyle.border){
|
||||
function mapColor(
|
||||
oStyle: CellStyle,
|
||||
border: Partial<Borders>,
|
||||
what: borderDir
|
||||
) {
|
||||
if (border[what] && border[what]?.style && oStyle.border) {
|
||||
oStyle.border[what] = [
|
||||
border[what].style?.toString(),
|
||||
"#" + getColor(border[what].color)
|
||||
]
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
border[what]!.style!.toString(),
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
"#" + getColor(border[what]!.color),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
console.log(wb);
|
||||
|
||||
const out = wb.worksheets.map((ws) => {
|
||||
const ows : SheetData = {
|
||||
const ows: SheetData = {
|
||||
name: ws.name,
|
||||
rows: {},
|
||||
cols: {},
|
||||
merges: [] ,
|
||||
|
||||
merges: [],
|
||||
|
||||
// freezes:
|
||||
};
|
||||
|
||||
ows.styles = [];
|
||||
|
||||
for(const col of ws.columns){
|
||||
if(col.width && ows.cols && col.number) {
|
||||
ows.cols[col.number-1] = {width: width2px(col.width)}
|
||||
if (ws.columns) {
|
||||
for (const col of ws.columns) {
|
||||
if (col.width && ows.cols && col.number) {
|
||||
ows.cols[col.number - 1] = { width: width2px(col.width) };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ws.eachRow((row, rowNumber) => {
|
||||
const rowId = (row.number - 1);
|
||||
const rowId = row.number - 1;
|
||||
const rowob: RowData = {
|
||||
cells: {}
|
||||
cells: {},
|
||||
};
|
||||
|
||||
if(ows.rows){
|
||||
|
||||
if (ows.rows) {
|
||||
ows.rows[rowId] = rowob;
|
||||
}
|
||||
if(row.height){
|
||||
if (row.height) {
|
||||
// px = pt * ( 72pt / 96 )
|
||||
|
||||
rowob.height = pt2px(row.height);
|
||||
}
|
||||
if(row.hidden) {
|
||||
if (row.hidden) {
|
||||
rowob.hidden = true;
|
||||
// TODO: implementit!
|
||||
}
|
||||
|
||||
row.eachCell((cell, cellNumber) => {
|
||||
const cellOb : CellData = {
|
||||
text: cell.text
|
||||
} ;
|
||||
const cellOb: CellData = {
|
||||
text: cell.text,
|
||||
};
|
||||
if (cell.formula) cellOb.text = "=" + cell.formula;
|
||||
|
||||
// style
|
||||
|
|
@ -76,59 +82,56 @@ export function toSpreadsheet(wb: Workbook) {
|
|||
const fgColor = cell.style.fill.fgColor;
|
||||
if (fgColor) {
|
||||
const hexColor = getColor(fgColor);
|
||||
if(hexColor) {
|
||||
if (hexColor) {
|
||||
oStyle.bgcolor = "#" + hexColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (cell.style.border) {
|
||||
|
||||
const border = cell.style.border;
|
||||
console.log(border)
|
||||
console.log(border);
|
||||
oStyle.border = {};
|
||||
["top","bottom","left","right"].forEach(what=>{
|
||||
mapColor(oStyle,border,what as borderDir);
|
||||
["top", "bottom", "left", "right"].forEach((what) => {
|
||||
mapColor(oStyle, border, what as borderDir);
|
||||
});
|
||||
|
||||
}
|
||||
if (cell.style.font) {
|
||||
const font = cell.style.font;
|
||||
|
||||
if(font.bold) {
|
||||
oStyle.font = oStyle.font || {}
|
||||
|
||||
if (font.bold) {
|
||||
oStyle.font = oStyle.font || {};
|
||||
oStyle.font.bold = true;
|
||||
}
|
||||
if(font.color) {
|
||||
if (font.color) {
|
||||
const hexColor = getColor(font.color);
|
||||
if(hexColor) {
|
||||
if (hexColor) {
|
||||
oStyle.color = "#" + hexColor;
|
||||
}
|
||||
}
|
||||
if(font.italic) {
|
||||
if (font.italic) {
|
||||
oStyle.font = oStyle.font || {};
|
||||
// oStyle.font
|
||||
(oStyle.font).italic = true;
|
||||
oStyle.font.italic = true;
|
||||
}
|
||||
if(font.strike) {
|
||||
(oStyle).strike = true;
|
||||
if (font.strike) {
|
||||
oStyle.strike = true;
|
||||
}
|
||||
if(font.underline) {
|
||||
(oStyle).underline = true;
|
||||
if (font.underline) {
|
||||
oStyle.underline = true;
|
||||
}
|
||||
if(font.name) {
|
||||
if (font.name) {
|
||||
oStyle.font = oStyle.font || {};
|
||||
(oStyle.font).name = font.name;
|
||||
oStyle.font.name = font.name;
|
||||
}
|
||||
if(font.family){
|
||||
if (font.family) {
|
||||
oStyle.font = oStyle.font || {};
|
||||
oStyle.font.family = font.family;
|
||||
}
|
||||
if(font.size) {
|
||||
if (font.size) {
|
||||
oStyle.font = oStyle.font || {};
|
||||
(oStyle.font).size = font.size;
|
||||
oStyle.font.size = font.size;
|
||||
}
|
||||
// if(font.vertAlign) {
|
||||
// console.log("here");
|
||||
|
|
@ -136,53 +139,51 @@ export function toSpreadsheet(wb: Workbook) {
|
|||
}
|
||||
if (cell.style.alignment) {
|
||||
//
|
||||
const alig = cell.style.alignment
|
||||
if(alig.vertical){
|
||||
const alig = cell.style.alignment;
|
||||
if (alig.vertical) {
|
||||
(oStyle as any).valign = alig.vertical;
|
||||
}
|
||||
if(alig.horizontal){
|
||||
if (alig.horizontal) {
|
||||
(oStyle as any).align = alig.horizontal;
|
||||
}
|
||||
if(cell.style.alignment.wrapText) {
|
||||
if (cell.style.alignment.wrapText) {
|
||||
oStyle.textwrap = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (cell.style.numFmt) {
|
||||
const numFmt = cell.style.numFmt;
|
||||
if(numFmt.endsWith('%')){
|
||||
(oStyle as any).format = 'percent';
|
||||
if (numFmt.endsWith("%")) {
|
||||
(oStyle as any).format = "percent";
|
||||
// TODO: 0.00%
|
||||
} else if (numFmt.contains('€')) {
|
||||
(oStyle as any).format = 'eur';
|
||||
} else if (numFmt.contains('$')) {
|
||||
(oStyle as any).format = 'usd';
|
||||
} else if (numFmt.contains("€")) {
|
||||
(oStyle as any).format = "eur";
|
||||
} else if (numFmt.contains("$")) {
|
||||
(oStyle as any).format = "usd";
|
||||
} else if (numFmt === "@") {
|
||||
(oStyle as any).format = 'text';
|
||||
(oStyle as any).format = "text";
|
||||
}
|
||||
// TODO: dates mm-dd-yy
|
||||
// TODO: [$-F800]dddd, mmmm dd, yyyy
|
||||
// TODO: 0.00
|
||||
// TODO: [$-F400]h:mm:ss AM/PM
|
||||
// TODO: 0.00E+00
|
||||
console.log(numFmt)
|
||||
console.log(numFmt);
|
||||
}
|
||||
if (cell.style.protection) {
|
||||
//TODO:
|
||||
}
|
||||
|
||||
if(Object.keys(oStyle).length>0 && ows.styles){
|
||||
const j = JSON.stringify(oStyle)
|
||||
let styleIndex = ows.styles.findIndex(s =>
|
||||
JSON.stringify(s) == j
|
||||
)
|
||||
if(styleIndex<0) {
|
||||
if (Object.keys(oStyle).length > 0 && ows.styles) {
|
||||
const j = JSON.stringify(oStyle);
|
||||
let styleIndex = ows.styles.findIndex(
|
||||
(s) => JSON.stringify(s) == j
|
||||
);
|
||||
if (styleIndex < 0) {
|
||||
ows.styles?.push(oStyle);
|
||||
styleIndex = ows.styles.length-1;
|
||||
styleIndex = ows.styles.length - 1;
|
||||
}
|
||||
cellOb.style = styleIndex;
|
||||
}
|
||||
|
||||
|
||||
if (!cell.isMerged || !cell.model.master) {
|
||||
rowob.cells[Number(cell.col) - 1] = cellOb;
|
||||
|
|
@ -212,7 +213,11 @@ export function toSpreadsheet(wb: Workbook) {
|
|||
return out;
|
||||
}
|
||||
function pt2px(pt: number) {
|
||||
return Math.round(pt * 1.33333);
|
||||
return Math.round(pt * 1.3333333);
|
||||
}
|
||||
|
||||
function px2pt(px: number) {
|
||||
return Math.round(px * 0.75);
|
||||
}
|
||||
|
||||
function width2px(w: number) {
|
||||
|
|
@ -221,6 +226,10 @@ function width2px(w: number) {
|
|||
return Math.round(w * 6.4);
|
||||
}
|
||||
|
||||
function px2width(px: number) {
|
||||
return Math.round(px * 0.15625);
|
||||
}
|
||||
|
||||
function getColor(fgColor: any) {
|
||||
if (fgColor.argb) {
|
||||
const hex = fgColor.argb.substring(2);
|
||||
|
|
@ -234,3 +243,57 @@ function getColor(fgColor: any) {
|
|||
}
|
||||
}
|
||||
|
||||
export function toExcelJS(data: SheetData[]): Workbook {
|
||||
const workbook = new Workbook();
|
||||
console.log(data);
|
||||
for (const ssheet of data) {
|
||||
const wsheet = workbook.addWorksheet(ssheet.name);
|
||||
|
||||
if (ssheet.cols !== undefined) {
|
||||
const colIds = Object.keys(ssheet.cols)
|
||||
.filter((key) => !isNaN(Number(key)))
|
||||
.map((key) => Number(key));
|
||||
|
||||
const maxColid = Math.max(...colIds);
|
||||
|
||||
const wscols: Partial<Column>[] = [];
|
||||
for (let colid = 0; colid <= maxColid; colid++) {
|
||||
const num = colid + 1;
|
||||
const col: Partial<Column> = {
|
||||
number: num,
|
||||
key: num.toString(),
|
||||
};
|
||||
const scol = ssheet.cols[colid];
|
||||
|
||||
if (scol?.width) {
|
||||
col.width = px2width(scol.width);
|
||||
}
|
||||
wscols.push(col);
|
||||
}
|
||||
|
||||
wsheet.columns = wscols;
|
||||
}
|
||||
|
||||
if (ssheet.rows !== undefined) {
|
||||
for (const rowId in ssheet.rows) {
|
||||
if (!isNaN(Number(rowId))) {
|
||||
const rowNum = Number(rowId);
|
||||
const rowdata = ssheet.rows[rowNum];
|
||||
|
||||
const row = wsheet.getRow(rowNum + 1);
|
||||
// cells, height, hidden
|
||||
if (rowdata.hidden) {
|
||||
row.hidden = true;
|
||||
}
|
||||
for (const cellId in rowdata.cells) {
|
||||
const cellNum = Number(cellId);
|
||||
const celldata = rowdata.cells[cellNum];
|
||||
const cell = row.getCell(cellNum + 1);
|
||||
cell.value = celldata.text;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return workbook;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,6 @@
|
|||
},
|
||||
"include": [
|
||||
"**/*.ts","**/*.tsx","**/*.svg"
|
||||
]
|
||||
],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue