Loading bgcolor WIP

This commit is contained in:
Gabriele Cannata 2023-08-04 19:45:07 +02:00
parent fff586950b
commit a3baa9e72e
4 changed files with 483 additions and 38 deletions

318
officeTheme.xml Normal file
View file

@ -0,0 +1,318 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
<a:themeElements>
<a:clrScheme name="Office">
<a:dk1>
<a:sysClr val="windowText" lastClr="000000" />
</a:dk1>
<a:lt1>
<a:sysClr val="window" lastClr="FFFFFF" />
</a:lt1>
<a:dk2>
<a:srgbClr val="1F497D" />
</a:dk2>
<a:lt2>
<a:srgbClr val="EEECE1" />
</a:lt2>
<a:accent1>
<a:srgbClr val="4F81BD" />
</a:accent1>
<a:accent2>
<a:srgbClr val="C0504D" />
</a:accent2>
<a:accent3>
<a:srgbClr val="9BBB59" />
</a:accent3>
<a:accent4>
<a:srgbClr val="8064A2" />
</a:accent4>
<a:accent5>
<a:srgbClr val="4BACC6" />
</a:accent5>
<a:accent6>
<a:srgbClr val="F79646" />
</a:accent6>
<a:hlink>
<a:srgbClr val="0000FF" />
</a:hlink>
<a:folHlink>
<a:srgbClr val="800080" />
</a:folHlink>
</a:clrScheme>
<a:fontScheme name="Office">
<a:majorFont>
<a:latin typeface="Cambria" />
<a:ea typeface="" />
<a:cs typeface="" />
<a:font script="Jpan" typeface=" Pゴシック" />
<a:font script="Hang" typeface="맑은 고딕" />
<a:font script="Hans" typeface="宋体" />
<a:font script="Hant" typeface="新細明體" />
<a:font script="Arab" typeface="Times New Roman" />
<a:font script="Hebr" typeface="Times New Roman" />
<a:font script="Thai" typeface="Tahoma" />
<a:font script="Ethi" typeface="Nyala" />
<a:font script="Beng" typeface="Vrinda" />
<a:font script="Gujr" typeface="Shruti" />
<a:font script="Khmr" typeface="MoolBoran" />
<a:font script="Knda" typeface="Tunga" />
<a:font script="Guru" typeface="Raavi" />
<a:font script="Cans" typeface="Euphemia" />
<a:font script="Cher" typeface="Plantagenet Cherokee" />
<a:font script="Yiii" typeface="Microsoft Yi Baiti" />
<a:font script="Tibt" typeface="Microsoft Himalaya" />
<a:font script="Thaa" typeface="MV Boli" />
<a:font script="Deva" typeface="Mangal" />
<a:font script="Telu" typeface="Gautami" />
<a:font script="Taml" typeface="Latha" />
<a:font script="Syrc" typeface="Estrangelo Edessa" />
<a:font script="Orya" typeface="Kalinga" />
<a:font script="Mlym" typeface="Kartika" />
<a:font script="Laoo" typeface="DokChampa" />
<a:font script="Sinh" typeface="Iskoola Pota" />
<a:font script="Mong" typeface="Mongolian Baiti" />
<a:font script="Viet" typeface="Times New Roman" />
<a:font script="Uigh" typeface="Microsoft Uighur" />
<a:font script="Geor" typeface="Sylfaen" />
</a:majorFont>
<a:minorFont>
<a:latin typeface="Calibri" />
<a:ea typeface="" />
<a:cs typeface="" />
<a:font script="Jpan" typeface=" Pゴシック" />
<a:font script="Hang" typeface="맑은 고딕" />
<a:font script="Hans" typeface="宋体" />
<a:font script="Hant" typeface="新細明體" />
<a:font script="Arab" typeface="Arial" />
<a:font script="Hebr" typeface="Arial" />
<a:font script="Thai" typeface="Tahoma" />
<a:font script="Ethi" typeface="Nyala" />
<a:font script="Beng" typeface="Vrinda" />
<a:font script="Gujr" typeface="Shruti" />
<a:font script="Khmr" typeface="DaunPenh" />
<a:font script="Knda" typeface="Tunga" />
<a:font script="Guru" typeface="Raavi" />
<a:font script="Cans" typeface="Euphemia" />
<a:font script="Cher" typeface="Plantagenet Cherokee" />
<a:font script="Yiii" typeface="Microsoft Yi Baiti" />
<a:font script="Tibt" typeface="Microsoft Himalaya" />
<a:font script="Thaa" typeface="MV Boli" />
<a:font script="Deva" typeface="Mangal" />
<a:font script="Telu" typeface="Gautami" />
<a:font script="Taml" typeface="Latha" />
<a:font script="Syrc" typeface="Estrangelo Edessa" />
<a:font script="Orya" typeface="Kalinga" />
<a:font script="Mlym" typeface="Kartika" />
<a:font script="Laoo" typeface="DokChampa" />
<a:font script="Sinh" typeface="Iskoola Pota" />
<a:font script="Mong" typeface="Mongolian Baiti" />
<a:font script="Viet" typeface="Arial" />
<a:font script="Uigh" typeface="Microsoft Uighur" />
<a:font script="Geor" typeface="Sylfaen" />
</a:minorFont>
</a:fontScheme>
<a:fmtScheme name="Office">
<a:fillStyleLst>
<a:solidFill>
<a:schemeClr val="phClr" />
</a:solidFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0">
<a:schemeClr val="phClr">
<a:tint val="50000" />
<a:satMod val="300000" />
</a:schemeClr>
</a:gs>
<a:gs pos="35000">
<a:schemeClr val="phClr">
<a:tint val="37000" />
<a:satMod val="300000" />
</a:schemeClr>
</a:gs>
<a:gs pos="100000">
<a:schemeClr val="phClr">
<a:tint val="15000" />
<a:satMod val="350000" />
</a:schemeClr>
</a:gs>
</a:gsLst>
<a:lin ang="16200000" scaled="1" />
</a:gradFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0">
<a:schemeClr val="phClr">
<a:tint val="100000" />
<a:shade val="100000" />
<a:satMod val="130000" />
</a:schemeClr>
</a:gs>
<a:gs pos="100000">
<a:schemeClr val="phClr">
<a:tint val="50000" />
<a:shade val="100000" />
<a:satMod val="350000" />
</a:schemeClr>
</a:gs>
</a:gsLst>
<a:lin ang="16200000" scaled="0" />
</a:gradFill>
</a:fillStyleLst>
<a:lnStyleLst>
<a:ln w="9525" cap="flat" cmpd="sng" algn="ctr">
<a:solidFill>
<a:schemeClr val="phClr">
<a:shade val="95000" />
<a:satMod val="105000" />
</a:schemeClr>
</a:solidFill>
<a:prstDash val="solid" />
</a:ln>
<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr">
<a:solidFill>
<a:schemeClr val="phClr" />
</a:solidFill>
<a:prstDash val="solid" />
</a:ln>
<a:ln w="38100" cap="flat" cmpd="sng" algn="ctr">
<a:solidFill>
<a:schemeClr val="phClr" />
</a:solidFill>
<a:prstDash val="solid" />
</a:ln>
</a:lnStyleLst>
<a:effectStyleLst>
<a:effectStyle>
<a:effectLst>
<a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0">
<a:srgbClr val="000000">
<a:alpha val="38000" />
</a:srgbClr>
</a:outerShdw>
</a:effectLst>
</a:effectStyle>
<a:effectStyle>
<a:effectLst>
<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
<a:srgbClr val="000000">
<a:alpha val="35000" />
</a:srgbClr>
</a:outerShdw>
</a:effectLst>
</a:effectStyle>
<a:effectStyle>
<a:effectLst>
<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0">
<a:srgbClr val="000000">
<a:alpha val="35000" />
</a:srgbClr>
</a:outerShdw>
</a:effectLst>
<a:scene3d>
<a:camera prst="orthographicFront">
<a:rot lat="0" lon="0" rev="0" />
</a:camera>
<a:lightRig rig="threePt" dir="t">
<a:rot lat="0" lon="0" rev="1200000" />
</a:lightRig>
</a:scene3d>
<a:sp3d>
<a:bevelT w="63500" h="25400" />
</a:sp3d>
</a:effectStyle>
</a:effectStyleLst>
<a:bgFillStyleLst>
<a:solidFill>
<a:schemeClr val="phClr" />
</a:solidFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0">
<a:schemeClr val="phClr">
<a:tint val="40000" />
<a:satMod val="350000" />
</a:schemeClr>
</a:gs>
<a:gs pos="40000">
<a:schemeClr val="phClr">
<a:tint val="45000" />
<a:shade val="99000" />
<a:satMod val="350000" />
</a:schemeClr>
</a:gs>
<a:gs pos="100000">
<a:schemeClr val="phClr">
<a:shade val="20000" />
<a:satMod val="255000" />
</a:schemeClr>
</a:gs>
</a:gsLst>
<a:path path="circle">
<a:fillToRect l="50000" t="-80000" r="50000" b="180000" />
</a:path>
</a:gradFill>
<a:gradFill rotWithShape="1">
<a:gsLst>
<a:gs pos="0">
<a:schemeClr val="phClr">
<a:tint val="80000" />
<a:satMod val="300000" />
</a:schemeClr>
</a:gs>
<a:gs pos="100000">
<a:schemeClr val="phClr">
<a:shade val="30000" />
<a:satMod val="200000" />
</a:schemeClr>
</a:gs>
</a:gsLst>
<a:path path="circle">
<a:fillToRect l="50000" t="50000" r="50000" b="50000" />
</a:path>
</a:gradFill>
</a:bgFillStyleLst>
</a:fmtScheme>
</a:themeElements>
<a:objectDefaults>
<a:spDef>
<a:spPr />
<a:bodyPr />
<a:lstStyle />
<a:style>
<a:lnRef idx="1">
<a:schemeClr val="accent1" />
</a:lnRef>
<a:fillRef idx="3">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="2">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="lt1" />
</a:fontRef>
</a:style>
</a:spDef>
<a:lnDef>
<a:spPr />
<a:bodyPr />
<a:lstStyle />
<a:style>
<a:lnRef idx="2">
<a:schemeClr val="accent1" />
</a:lnRef>
<a:fillRef idx="0">
<a:schemeClr val="accent1" />
</a:fillRef>
<a:effectRef idx="1">
<a:schemeClr val="accent1" />
</a:effectRef>
<a:fontRef idx="minor">
<a:schemeClr val="tx1" />
</a:fontRef>
</a:style>
</a:lnDef>
</a:objectDefaults>
<a:extraClrSchemeLst />
</a:theme>

View file

@ -150,7 +150,7 @@ export function processCodeBlock(
tip: "Save",
icon: saveIcon,
shortcut: "Ctrl+S",
onClick: (s, d) => saveDataIntoBlock(s, d, ctx),
onClick: (s: any, d: any) => saveDataIntoBlock(s, d, ctx),
},
],
};
@ -162,15 +162,15 @@ export function processCodeBlock(
const xlsx = XLSX.read(fileContent, {
cellStyles: true,
sheetStubs: true // >
sheetStubs: true, // >
});
const workbook = new ExcelJS.Workbook();
const excelWorkbook = await workbook.xlsx.load(fileContent)
const excelWorkbook = await workbook.xlsx.load(fileContent);
const data2 = toSpreadsheet(excelWorkbook);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const data = stox(xlsx);
(ctx as any).spreadsheet = createSpreadSheet(
container,
@ -207,7 +207,8 @@ function saveDataIntoBlock(
const s = (ctx as any).spreadsheet;
const dts = s.getData();
const view: MarkdownView = app.workspace.getActiveViewOfType(MarkdownView);
const view = app.workspace.getActiveViewOfType(MarkdownView);
if (!view) return;
if (view.getMode() === "source") {
const sec = ctx.getSectionInfo((ctx as any).el as HTMLElement);
if (sec) {
@ -251,7 +252,7 @@ function createSpreadSheet(
type: "buffer",
compression: true,
bookSST: true,
cellStyles: true
cellStyles: true,
});
// fs.writeFile(filename,bytes);
app.vault.adapter.writeBinary(options.filename, bytes);
@ -270,11 +271,11 @@ function createSpreadSheet(
function applyStyles(ssdata: any, wb: XLSX.WorkBook) {
console.log(ssdata, wb);
for (let sheet of ssdata) {
for (const sheet of ssdata) {
const { name, styles, rows } = sheet;
for (let rowId in rows) {
for (const rowId in rows) {
const cells = rows[rowId]["cells"];
for (let cellId in cells) {
for (const cellId in cells) {
const cell = cells[cellId];
if (cell.style !== undefined) {
const wbStyle = styleSS2WB(styles[cell.style]);

67
src/utils/excelColors.ts Normal file
View file

@ -0,0 +1,67 @@
// Sample theme color index
// const themeColorIndex = 1; // The theme color index (0-9)
// const tintVal = -0.5; // The tint value (-1 to 1)
// Sample Office Color Themes
const officeThemeColors = [
[255, 255, 255], // White
[0, 0, 0], // Black
[238, 236, 225], // Tan
[31, 73, 125], // Dark Blue
[79, 129, 189], // Blue
[192, 80, 77], // Red
[155, 187, 89], // Green
[128, 100, 162], // Purple
[75, 172, 198], // Aqua
[245, 150, 70], // Orange
];
const RGBToHSL = (r:number, g:number, b:number) => {
r /= 255;
g /= 255;
b /= 255;
const l = Math.max(r, g, b);
const s = l - Math.min(r, g, b);
const h = s
? l === r
? (g - b) / s
: l === g
? 2 + (b - r) / s
: 4 + (r - g) / s
: 0;
return [
60 * h < 0 ? 60 * h + 360 : 60 * h,
100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
(100 * (2 * l - s)) / 2,
];
};
// TODO: read theme from XML
export function convertThemeColorToRGB(
themeColorIndex: number,
tintVal: number
) {
const baseColor = officeThemeColors[themeColorIndex];
const baseHSL = RGBToHSL(baseColor[0],baseColor[1], baseColor[2]) //rgb2hsl(baseColor);
const lumination = baseHSL[2];
if (tintVal < 0) {
baseHSL[2] = lumination * (1.0 + tintVal);
} else {
baseHSL[2] = lumination * (1.0 - tintVal) + 100 * tintVal;
}
// return HSLToRGB(baseHSL[0] / 360, baseHSL[1] / 100, baseHSL[2] / 100);
return hsl2rgb(baseHSL[0], baseHSL[1] / 100, baseHSL[2] / 100);
}
// input: h as an angle in [0,360] and s,l in [0,1]
function hsl2rgb(h:number,s:number,l:number)
{
const a=s*Math.min(l,1-l);
const f= (n:number,k=(n+h/30)%12) => l - a*Math.max(Math.min(k-3,9-k,1),-1);
return [f(0)*255,f(8)*255,f(4)*255].map(Math.round);
}
export function rgbToHex(r:number, g:number, b:number) {
return r.toString(16) + g.toString(16) + b.toString(16);
}

View file

@ -1,47 +1,106 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Workbook } from "exceljs";
import { convertThemeColorToRGB, rgbToHex } from "./excelColors";
export function toSpreadsheet(wb: Workbook) {
const out = wb.worksheets.map(ws=>{
const out = wb.worksheets.map((ws) => {
const ows = {
name: ws.name,
rows: {} as any,
merges: [] as string[],
styles: [] as any[],
// freezes:
}
};
ws.eachRow((row, rowNumber) => {
const rowId = String(row.number-1)
const rowId = String(row.number - 1);
const rowob: any = {
cells: {}
cells: {},
};
ows.rows[rowId] = rowob;
const cells = row.eachCell((cell,cellNumber)=>{
row.eachCell((cell, cellNumber) => {
const cellOb = {
text: cell.text,
merge: [] as number[]
}
text: cell.text
} as any;
if (cell.formula) cellOb.text = "=" + cell.formula;
// style
const oStyle: any = {};
if (cell.style.fill) {
//
// console.log(cell.style.fill);
if (cell.style.fill.type === "pattern") {
const fgColor = cell.style.fill.fgColor;
if (fgColor) {
if (fgColor.argb) {
//
} else if (fgColor.theme !== undefined) {
const theme = fgColor?.theme;
const tint = (fgColor as any).tint || 0;
const rgb = convertThemeColorToRGB(theme, tint);
const hex = rgbToHex(rgb[0],rgb[1],rgb[2]);
oStyle.bgcolor = "#" + hex;
}
}
}
}
if (cell.style.border) {
//
}
if (cell.style.font) {
//
}
if (cell.style.alignment) {
//
}
if (cell.style.numFmt) {
//
}
if (cell.style.protection) {
//
}
if(Object.keys(oStyle).length>0){
console.log(oStyle);
// TODO: index it and put index in cell
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;
}
cellOb.style = styleIndex;
}
if (!cell.isMerged || !cell.model.master) {
rowob.cells[Number(cell.col) - 1] = cellOb;
if (cell.isMerged) {
const merge = (ws as any)._merges[cell.address];
// console.log(merge);
cellOb.merge = [
merge.bottom-merge.top as number,
merge.right-merge.left as number
]
(merge.bottom - merge.top) as number,
(merge.right - merge.left) as number,
];
}
} else {
//
}
})
})
});
});
// merges
const merges = [];
for(let m in (ws as any)._merges){
for (const m in (ws as any)._merges) {
const merge = (ws as any)._merges[m];
const range = merge.range
const range = merge.range;
merges.push(range);
}
ows.merges = merges;