mirror of
https://github.com/ljcoder2015/obsidian-excel.git
synced 2026-07-22 08:30:28 +00:00
Compare commits
48 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9df140382 | ||
|
|
04dc273d80 | ||
|
|
5e149efaa7 | ||
|
|
583c46a828 | ||
|
|
5397aade29 | ||
|
|
82a6a7d1f9 | ||
|
|
56ca68dde1 | ||
|
|
5380c7a6e9 | ||
|
|
b018f956a7 | ||
|
|
ff08a53c06 | ||
|
|
05ea79123b | ||
|
|
2135848b38 | ||
|
|
8d2a44df50 | ||
|
|
34f35f9822 | ||
|
|
42cbe19ad0 | ||
|
|
6dc364519b | ||
|
|
9898398afc | ||
|
|
ae4426b24f | ||
|
|
0346ab7ca3 | ||
|
|
63c041ba05 | ||
|
|
a1c620d4e2 | ||
|
|
578a3388c6 | ||
|
|
1bb57398d2 | ||
|
|
4d784ac627 | ||
|
|
2e8ee0f5ac | ||
|
|
231ab55de6 | ||
|
|
8908dd9da4 | ||
|
|
5e98093f49 | ||
|
|
3aa557087a | ||
|
|
8bbebb9a6f | ||
|
|
ed685da21c | ||
|
|
2457eff3d1 | ||
|
|
8ad8fe21e6 | ||
|
|
a8ce218640 | ||
|
|
10f2e6742a | ||
|
|
c70a1aa080 | ||
|
|
c3c97b9204 | ||
|
|
914a90021b | ||
|
|
9aa99436b9 | ||
|
|
d31a59c76a | ||
|
|
a12cb3a222 | ||
|
|
a52bc92027 | ||
|
|
437a3d4a3f | ||
|
|
e19c7ced50 | ||
|
|
c8bf177971 | ||
|
|
fcbf77855e | ||
|
|
e5a36707ff | ||
|
|
4cfdda2059 |
18 changed files with 2958 additions and 938 deletions
1
.github/workflows/release.yml
vendored
1
.github/workflows/release.yml
vendored
|
|
@ -19,6 +19,7 @@ jobs:
|
|||
|
||||
- name: Build plugin
|
||||
run: |
|
||||
npm config set strict-ssl false
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
|
|
|
|||
18
README.md
18
README.md
|
|
@ -1,3 +1,6 @@
|
|||
> ### The Obsidian-Excel plugin will no longer be maintained or updated. To download Obsidian-Sheet-Plus, please visit [https://github.com/ljcoder2015/obsidian-sheet-plus](https://github.com/ljcoder2015/obsidian-sheet-plus)
|
||||
> ### Obsidian-Excel插件不再更新维护,旧功能不满足可以尝试使用新插件Obsidian-Sheet-Plus。下载地址 [https://github.com/ljcoder2015/obsidian-sheet-plus](https://github.com/ljcoder2015/obsidian-sheet-plus)
|
||||
|
||||
# Obsidian Excel Plugin
|
||||
|
||||
## Excel
|
||||
|
|
@ -15,7 +18,15 @@ If you are using Microsoft Office 365 to create xlsx files, you need to import t
|
|||
|
||||
embed link rule:
|
||||
|
||||
> ![[`file-folder`/`file-name`#`sheet-name`|`sri`-`sci`:`eri`-`eci`<`sheet-height`>]]
|
||||
```![[file-folder/file-name#sheet-name|sri-sci:eri-eci<sheet-height>{html}]]```
|
||||
|
||||
- `sri`: Start row index
|
||||
- `eri`: End row index
|
||||
- `sci`: Start column index
|
||||
- `eci`: End column index
|
||||
- `{html}`: Whether to display as HTML
|
||||
- `<sheet-height>`: Sheet height, dispaly HTML not work
|
||||
|
||||
|
||||

|
||||
|
||||
|
|
@ -23,6 +34,8 @@ embed link rule:
|
|||
|
||||

|
||||
|
||||

|
||||
|
||||
### copy selected cells to HTML
|
||||
|
||||

|
||||
|
|
@ -39,4 +52,7 @@ embed link rule:
|
|||
|
||||
- ljcoder@163.com
|
||||
|
||||
### buy a Coffee
|
||||
|
||||
[https://ko-fi.com/ljcoder](https://ko-fi.com/ljcoder)
|
||||
|
||||
|
|
|
|||
BIN
doc/img/embed_html.gif
Normal file
BIN
doc/img/embed_html.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 502 KiB |
46
main.css
46
main.css
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"id": "excel",
|
||||
"name": "Excel",
|
||||
"version": "1.3.8",
|
||||
"version": "1.3.24",
|
||||
"minAppVersion": "0.15.0",
|
||||
"description": "Create spreadsheets and easily embed them in Markdown",
|
||||
"author": "ljcoder",
|
||||
"authorUrl": "https://github.com/ljcoder2015",
|
||||
"fundingUrl": "https://ko-fi.com/ljcoder",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
|
|
|
|||
2859
package-lock.json
generated
2859
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -6,8 +6,7 @@
|
|||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
||||
"postinstall": "patch-package"
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
|
|
@ -24,13 +23,12 @@
|
|||
"esbuild": "0.17.3",
|
||||
"esbuild-plugin-less": "^1.2.4",
|
||||
"obsidian": "latest",
|
||||
"patch-package": "^8.0.0",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "4.7.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"monkey-around": "^2.3.0",
|
||||
"x-data-spreadsheet": "^1.1.9",
|
||||
"x-data-spreadsheet": "git+ssh://git@github.com:ljcoder2015/x-spreadsheet.git#1.1.4",
|
||||
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
diff --git a/node_modules/x-data-spreadsheet/src/component/event.js b/node_modules/x-data-spreadsheet/src/component/event.js
|
||||
index cdbc0fa..cb2a9db 100644
|
||||
--- a/node_modules/x-data-spreadsheet/src/component/event.js
|
||||
+++ b/node_modules/x-data-spreadsheet/src/component/event.js
|
||||
@@ -74,6 +74,7 @@ export function bindTouch(target, { move, end }) {
|
||||
starty = pageY;
|
||||
}
|
||||
evt.preventDefault();
|
||||
+ evt.stopPropagation();
|
||||
});
|
||||
bind(target, 'touchend', (evt) => {
|
||||
if (!end) return;
|
||||
diff --git a/node_modules/x-data-spreadsheet/src/component/sheet.js b/node_modules/x-data-spreadsheet/src/component/sheet.js
|
||||
index 086b8c4..cd01f6e 100644
|
||||
--- a/node_modules/x-data-spreadsheet/src/component/sheet.js
|
||||
+++ b/node_modules/x-data-spreadsheet/src/component/sheet.js
|
||||
@@ -77,11 +77,11 @@ function selectorSet(multiple, ri, ci, indexesUpdated = true, moving = false) {
|
||||
const cell = data.getCell(ri, ci);
|
||||
if (multiple) {
|
||||
selector.setEnd(ri, ci, moving);
|
||||
- this.trigger('cells-selected', cell, selector.range);
|
||||
+ this.trigger('cells-selected', this.data, selector.range);
|
||||
} else {
|
||||
// trigger click event
|
||||
selector.set(ri, ci, indexesUpdated);
|
||||
- this.trigger('cell-selected', cell, ri, ci);
|
||||
+ this.trigger('cell-selected', this.data, ri, ci);
|
||||
}
|
||||
toolbar.reset();
|
||||
table.render();
|
||||
diff --git a/node_modules/x-data-spreadsheet/src/index.d.ts b/node_modules/x-data-spreadsheet/src/index.d.ts
|
||||
index 948a8e9..7fe36b3 100644
|
||||
--- a/node_modules/x-data-spreadsheet/src/index.d.ts
|
||||
+++ b/node_modules/x-data-spreadsheet/src/index.d.ts
|
||||
@@ -45,18 +45,18 @@ declare module 'x-data-spreadsheet' {
|
||||
export interface SpreadsheetEventHandler {
|
||||
(
|
||||
envt: CELL_SELECTED,
|
||||
- callback: (cell: Cell, rowIndex: number, colIndex: number) => void
|
||||
+ callback: (sheetData: Record<string, any>, rowIndex: number, colIndex: number) => void
|
||||
): void;
|
||||
(
|
||||
envt: CELLS_SELECTED,
|
||||
callback: (
|
||||
- cell: Cell,
|
||||
+ sheetData: Record<string, any>,
|
||||
parameters: { sri: number; sci: number; eri: number; eci: number }
|
||||
) => void
|
||||
): void;
|
||||
(
|
||||
evnt: CELL_EDITED,
|
||||
- callback: (text: string, rowIndex: number, colIndex: number) => void
|
||||
+ callback: (sheetData: Record<string, any>, rowIndex: number, colIndex: number) => void
|
||||
): void;
|
||||
}
|
||||
|
||||
@@ -182,6 +182,19 @@ declare module 'x-data-spreadsheet' {
|
||||
* @param callback
|
||||
*/
|
||||
change(callback: (json: Record<string, any>) => void): this;
|
||||
+
|
||||
+ /**
|
||||
+ * 添加sheet监听回调
|
||||
+ * @param callback
|
||||
+ */
|
||||
+ onAddSheet(callback: () => void): this;
|
||||
+
|
||||
+ /**
|
||||
+ * 重命名Sheet
|
||||
+ * @param callback
|
||||
+ */
|
||||
+ onRenameSheet(callback: () => void): this;
|
||||
+
|
||||
/**
|
||||
* set locale
|
||||
* @param lang
|
||||
diff --git a/node_modules/x-data-spreadsheet/src/index.js b/node_modules/x-data-spreadsheet/src/index.js
|
||||
index 479a0b7..96d0f3a 100644
|
||||
--- a/node_modules/x-data-spreadsheet/src/index.js
|
||||
+++ b/node_modules/x-data-spreadsheet/src/index.js
|
||||
@@ -20,6 +20,7 @@ class Spreadsheet {
|
||||
this.bottombar = this.options.showBottomBar ? new Bottombar(() => {
|
||||
const d = this.addSheet();
|
||||
this.sheet.resetData(d);
|
||||
+ this.sheet.trigger('add-sheet', "")
|
||||
}, (index) => {
|
||||
const d = this.datas[index];
|
||||
this.sheet.resetData(d);
|
||||
@@ -27,6 +28,7 @@ class Spreadsheet {
|
||||
this.deleteSheet();
|
||||
}, (index, value) => {
|
||||
this.datas[index].name = value;
|
||||
+ this.sheet.trigger('rename-sheet', value)
|
||||
}) : null;
|
||||
this.data = this.addSheet();
|
||||
const rootEl = h('div', `${cssPrefix}`)
|
||||
@@ -120,6 +122,16 @@ class Spreadsheet {
|
||||
return this;
|
||||
}
|
||||
|
||||
+ onAddSheet(cb) {
|
||||
+ this.sheet.on('add-sheet', cb);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
+ onRenameSheet(cb) {
|
||||
+ this.sheet.on('rename-sheet', cb);
|
||||
+ return this;
|
||||
+ }
|
||||
+
|
||||
static locale(lang, message) {
|
||||
locale(lang, message);
|
||||
}
|
||||
|
|
@ -15,6 +15,22 @@ export class ExcelSettingTab extends PluginSettingTab {
|
|||
|
||||
containerEl.empty()
|
||||
|
||||
containerEl.createEl("h1", { text: t("BASE_COLOR") });
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("BASE_COLOR"))
|
||||
.setDesc(t("BASE_COLOR_DESC"))
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption("light","Light")
|
||||
.addOption("dark","Dark")
|
||||
.setValue(this.plugin.settings.theme)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.theme = value
|
||||
this.plugin.saveSettings()
|
||||
}),
|
||||
);
|
||||
|
||||
containerEl.createEl("h1", { text: t("FILE_SETTING") });
|
||||
|
||||
new Setting(containerEl)
|
||||
|
|
@ -98,5 +114,46 @@ export class ExcelSettingTab extends PluginSettingTab {
|
|||
this.plugin.saveSettings()
|
||||
})
|
||||
)
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("DEFAULT_ROWS_LEN"))
|
||||
.setDesc(t("DEFAULT_ROWS_LEN_DESC"))
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("100")
|
||||
.setValue(this.plugin.settings.defaultRowsLen)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.defaultRowsLen = value
|
||||
this.plugin.saveSettings()
|
||||
})
|
||||
)
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("DEFAULT_COLS_LEN"))
|
||||
.setDesc(t("DEFAULT_COLS_LEN_DESC"))
|
||||
.addText((text) =>
|
||||
text
|
||||
.setPlaceholder("26")
|
||||
.setValue(this.plugin.settings.defaultColsLen)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.defaultColsLen = value
|
||||
this.plugin.saveSettings()
|
||||
})
|
||||
)
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t("SHOW_SHEET_BUTTON"))
|
||||
.setDesc(t("SHOW_SHEET_BUTTON_DESC"))
|
||||
.addDropdown((dropdown) =>
|
||||
dropdown
|
||||
.addOption("true","True")
|
||||
.addOption("false","False")
|
||||
.setValue(this.plugin.settings.showSheetButton)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.showSheetButton = value
|
||||
this.plugin.saveSettings()
|
||||
}),
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import ExcelPlugin from "src/main";
|
||||
import { TextFileView, WorkspaceLeaf, Platform, Notice, moment } from "obsidian";
|
||||
import { TextFileView, WorkspaceLeaf, Platform, Notice, moment, TFile } from "obsidian";
|
||||
import Spreadsheet from "x-data-spreadsheet";
|
||||
import * as XLSX from "xlsx";
|
||||
import { stox, xtos } from "./utils/xlsxspread";
|
||||
|
|
@ -8,6 +8,7 @@ import { getExcelData } from "./utils/DataUtils";
|
|||
import zhCn from "./lang/locale/sheet-zh-cn"
|
||||
import en from "./lang/locale/sheet-en"
|
||||
import { t } from "./lang/helpers"
|
||||
import { updateSheetTheme } from "./utils/ThemeUtils";
|
||||
|
||||
export class ExcelView extends TextFileView {
|
||||
public plugin: ExcelPlugin;
|
||||
|
|
@ -48,6 +49,13 @@ export class ExcelView extends TextFileView {
|
|||
saveData(data: string) {
|
||||
this.data = this.headerData() + data;
|
||||
// console.log("saveData", this.data)
|
||||
this.save(false)
|
||||
.then(() => {
|
||||
console.log("save data success", this.file)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("save data error", e)
|
||||
})
|
||||
}
|
||||
|
||||
clear(): void {
|
||||
|
|
@ -58,8 +66,8 @@ export class ExcelView extends TextFileView {
|
|||
this.data = data;
|
||||
|
||||
this.app.workspace.onLayoutReady(async () => {
|
||||
// console.log('setViewData')
|
||||
await this.refresh();
|
||||
// console.log('setViewData', this.file)
|
||||
this.refresh();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -78,11 +86,12 @@ export class ExcelView extends TextFileView {
|
|||
}
|
||||
const f = files[0];
|
||||
const reader = new FileReader();
|
||||
const self = this
|
||||
reader.onload = (e) => {
|
||||
const data = e.target?.result;
|
||||
|
||||
console.log('handleFile', self.file)
|
||||
if (data) {
|
||||
this.process_wb(XLSX.read(data));
|
||||
self.process_wb(XLSX.read(data));
|
||||
} else {
|
||||
new Notice(t("READ_FILE_FAILED"));
|
||||
}
|
||||
|
|
@ -93,8 +102,16 @@ export class ExcelView extends TextFileView {
|
|||
process_wb(wb: XLSX.WorkBook) {
|
||||
const sheetData = stox(wb);
|
||||
if (sheetData) {
|
||||
this.sheet.loadData(sheetData);
|
||||
this.saveData(JSON.stringify(sheetData));
|
||||
sheetData.forEach((sheet) => {
|
||||
var sheetAny = sheet as any
|
||||
if (sheetAny.rows) {
|
||||
const last = Object.keys(sheetAny.rows).last() || "100"
|
||||
const max = parseInt(this.plugin.settings.defaultRowsLen)
|
||||
sheetAny.rows.len = Math.max(max, parseInt(last) + 20)
|
||||
}
|
||||
})
|
||||
this.saveData(JSON.stringify(sheetData))
|
||||
this.refresh()
|
||||
} else {
|
||||
new Notice(t("DATA_PARSING_ERROR"));
|
||||
}
|
||||
|
|
@ -128,6 +145,7 @@ export class ExcelView extends TextFileView {
|
|||
|
||||
onload(): void {
|
||||
this.ownerWindow = this.containerEl.win;
|
||||
console.log("onload", this.file)
|
||||
|
||||
// 添加顶部导入按钮
|
||||
this.importEle = this.addAction("download", t("IMPORT_XLSX_FILE"), (ev) =>
|
||||
|
|
@ -179,6 +197,7 @@ export class ExcelView extends TextFileView {
|
|||
|
||||
// 初始化 sheet
|
||||
const jsonData = JSON.parse(getExcelData(this.data) || "{}") || {};
|
||||
// console.log("refresh", jsonData, this.file)
|
||||
|
||||
// 设置多语言
|
||||
if (moment.locale() === 'zh-cn') {
|
||||
|
|
@ -186,6 +205,41 @@ export class ExcelView extends TextFileView {
|
|||
} else {
|
||||
Spreadsheet.locale('en', en)
|
||||
}
|
||||
|
||||
// 设置 sheet 样式
|
||||
var style = {
|
||||
bgcolor: '#ffffff',
|
||||
align: 'left',
|
||||
valign: 'middle',
|
||||
textwrap: false,
|
||||
strike: false,
|
||||
underline: false,
|
||||
color: '#0a0a0a',
|
||||
font: {
|
||||
name: 'Helvetica',
|
||||
size: 10,
|
||||
bold: false,
|
||||
italic: false,
|
||||
},
|
||||
}
|
||||
|
||||
if (this.plugin.settings.theme === "dark") {
|
||||
style = {
|
||||
bgcolor: '#363636',
|
||||
align: 'left',
|
||||
valign: 'middle',
|
||||
textwrap: false,
|
||||
strike: false,
|
||||
underline: false,
|
||||
color: '#e6e6e6',
|
||||
font: {
|
||||
name: 'Helvetica',
|
||||
size: 10,
|
||||
bold: false,
|
||||
italic: false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
this.sheet = new Spreadsheet(this.sheetEle, {
|
||||
|
|
@ -195,21 +249,23 @@ export class ExcelView extends TextFileView {
|
|||
width: () => this.contentEl.clientWidth - 32,
|
||||
},
|
||||
row: {
|
||||
len: 100,
|
||||
len: parseInt(this.plugin.settings.defaultRowsLen),
|
||||
height: parseInt(this.plugin.settings.rowHeight),
|
||||
},
|
||||
col: {
|
||||
len: 26,
|
||||
len: parseInt(this.plugin.settings.defaultColsLen),
|
||||
width: parseInt(this.plugin.settings.colWidth),
|
||||
indexWidth: 60,
|
||||
minWidth: 60,
|
||||
},
|
||||
//@ts-ignore
|
||||
style: style,
|
||||
isDark: this.plugin.settings.theme === "dark"
|
||||
})
|
||||
.loadData(jsonData) // load data
|
||||
.change(() => {
|
||||
// save data to db
|
||||
const data = this.sheet.getData();
|
||||
// console.log("save data to db", data);
|
||||
this.saveData(JSON.stringify(data));
|
||||
})
|
||||
.onAddSheet(() => {
|
||||
|
|
@ -221,6 +277,11 @@ export class ExcelView extends TextFileView {
|
|||
const data = this.sheet.getData();
|
||||
// console.log('onRenameSheet', data)
|
||||
this.saveData(JSON.stringify(data));
|
||||
})
|
||||
.onDeleteSheet(() => {
|
||||
const data = this.sheet.getData();
|
||||
// console.log('onDeleteSheet', data)
|
||||
this.saveData(JSON.stringify(data));
|
||||
});
|
||||
|
||||
this.sheet.on("cells-selected", (sheetData, { sri, sci, eri, eci }) => {
|
||||
|
|
@ -241,6 +302,8 @@ export class ExcelView extends TextFileView {
|
|||
this.cellsSelected.eci = ci;
|
||||
});
|
||||
|
||||
updateSheetTheme(this.plugin.settings.theme === "dark")
|
||||
|
||||
// @ts-ignore
|
||||
this.sheet.validate();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,13 @@ import {
|
|||
} from "obsidian";
|
||||
import ExcelPlugin from "./main";
|
||||
import Spreadsheet from "x-data-spreadsheet";
|
||||
import { getExcelData, getExcelAreaData } from "./utils/DataUtils";
|
||||
import {
|
||||
getExcelData,
|
||||
getExcelAreaData,
|
||||
getExcelAreaHtml,
|
||||
} from "./utils/DataUtils";
|
||||
import { updateSheetTheme } from "./utils/ThemeUtils";
|
||||
import da from "./lang/locale/da";
|
||||
|
||||
let plugin: ExcelPlugin;
|
||||
let vault: Vault;
|
||||
|
|
@ -80,26 +86,45 @@ const tmpObsidianWYSIWYG = async (
|
|||
internalEmbedDiv.empty();
|
||||
|
||||
const data = await vault.read(file);
|
||||
const src = internalEmbedDiv.getAttribute("src") ?? "";
|
||||
const alt = internalEmbedDiv.getAttribute("alt") ?? "";
|
||||
var src = internalEmbedDiv.getAttribute("src") ?? "";
|
||||
// 是否转换成HTML
|
||||
var toHTML = false;
|
||||
if (src.includes("{html}")) {
|
||||
toHTML = true;
|
||||
src = src.replace("{html}", "");
|
||||
}
|
||||
|
||||
alt = internalEmbedDiv.getAttribute("alt") ?? "";
|
||||
if (alt.includes("{html}")) {
|
||||
// 单 sheet 中的某一区域
|
||||
toHTML = true;
|
||||
alt = alt.replace("{html}", "");
|
||||
}
|
||||
|
||||
const split = src.split("#");
|
||||
var excelData = getExcelData(data);
|
||||
if (split.length > 1) {
|
||||
excelData = getExcelAreaData(
|
||||
data,
|
||||
split[1],
|
||||
alt
|
||||
excelData = getExcelAreaData(data, split[1], alt);
|
||||
}
|
||||
|
||||
// 生成内容
|
||||
if (toHTML) {
|
||||
const table = createEditSheetHtml(data, file, split[1], alt)
|
||||
internalEmbedDiv.appendChild(table);
|
||||
} else {
|
||||
const sheetDiv = createSheetEl(
|
||||
excelData,
|
||||
file,
|
||||
internalEmbedDiv.clientWidth
|
||||
);
|
||||
internalEmbedDiv.appendChild(sheetDiv);
|
||||
}
|
||||
|
||||
const sheetDiv = createSheetEl(excelData, file, internalEmbedDiv.clientWidth);
|
||||
if (markdownEmbed) {
|
||||
//display image on canvas without markdown frame
|
||||
internalEmbedDiv.removeClass("markdown-embed");
|
||||
internalEmbedDiv.removeClass("inline-embed");
|
||||
}
|
||||
internalEmbedDiv.appendChild(sheetDiv);
|
||||
// console.log('internalEmbedDiv', internalEmbedDiv, markdownEmbed)
|
||||
}
|
||||
|
||||
el.empty();
|
||||
|
|
@ -112,73 +137,234 @@ const tmpObsidianWYSIWYG = async (
|
|||
internalEmbedDiv.empty();
|
||||
|
||||
const data = await vault.read(file);
|
||||
const src = internalEmbedDiv.getAttribute("src") ?? "";
|
||||
const alt = internalEmbedDiv.getAttribute("alt") ?? "";
|
||||
var range = alt
|
||||
var src = internalEmbedDiv.getAttribute("src") ?? "";
|
||||
|
||||
var heigh = parseInt(plugin.settings.sheetHeight)
|
||||
// 是否转换成HTML
|
||||
var toHTML = false;
|
||||
if (src.includes("{html}")) {
|
||||
// 单 sheet
|
||||
toHTML = true;
|
||||
src = src.replace("{html}", "");
|
||||
}
|
||||
|
||||
var alt = internalEmbedDiv.getAttribute("alt") ?? "";
|
||||
if (alt.includes("{html}")) {
|
||||
// 单 sheet 中的某一区域
|
||||
toHTML = true;
|
||||
alt = alt.replace("{html}", "");
|
||||
}
|
||||
|
||||
var heigh = parseInt(plugin.settings.sheetHeight);
|
||||
const matchResult = alt.match(/<(\d+)>/);
|
||||
|
||||
if (matchResult && matchResult.length > 1) {
|
||||
const extractedValue = matchResult[1]; // 获取匹配到的数字
|
||||
// console.log("Extracted value:", extractedValue);
|
||||
heigh = parseInt(extractedValue)
|
||||
range = range.replace(/<\d+>/, '');
|
||||
const extractedValue = matchResult[1]; // 获取匹配到的数字
|
||||
// console.log("Extracted value:", extractedValue);
|
||||
heigh = parseInt(extractedValue);
|
||||
alt = alt.replace(/<\d+>/, "");
|
||||
} else {
|
||||
// console.log("No match found.");
|
||||
// console.log("No match found.");
|
||||
}
|
||||
|
||||
const split = src.split("#");
|
||||
var excelData = getExcelData(data);
|
||||
if (split.length > 1) {
|
||||
excelData = getExcelAreaData(
|
||||
data,
|
||||
split[1],
|
||||
range
|
||||
);
|
||||
excelData = getExcelAreaData(data, split[1], alt);
|
||||
}
|
||||
|
||||
// console.log('internalEmbedDiv', excelData, src, alt)
|
||||
const sheetDiv = createSheetEl(excelData, file, internalEmbedDiv.clientWidth, heigh);
|
||||
if (toHTML) {
|
||||
const table = createEditSheetHtml(data, file, split[1], alt)
|
||||
internalEmbedDiv.appendChild(table);
|
||||
} else {
|
||||
const sheetDiv = createSheetEl(
|
||||
excelData,
|
||||
file,
|
||||
internalEmbedDiv.clientWidth,
|
||||
heigh
|
||||
);
|
||||
internalEmbedDiv.appendChild(sheetDiv);
|
||||
}
|
||||
if (markdownEmbed) {
|
||||
//display image on canvas without markdown frame
|
||||
internalEmbedDiv.removeClass("markdown-embed");
|
||||
internalEmbedDiv.removeClass("inline-embed");
|
||||
}
|
||||
internalEmbedDiv.appendChild(sheetDiv);
|
||||
};
|
||||
|
||||
const createSheetEl = (data: string, file: TFile, width: number, height: number = 300): HTMLDivElement => {
|
||||
|
||||
const sheetDiv = createDiv()
|
||||
/**
|
||||
* 编辑模式下转换成 HTML 显示
|
||||
* @param data markdown 文件原始data
|
||||
* @param sheet sheet 名称
|
||||
* @param cells 选中的cells 格式为: sri-sci:eri-eci 例如 6-6:7-8
|
||||
* @returns
|
||||
*/
|
||||
const createEditSheetHtml = (
|
||||
excelData: string,
|
||||
file: TFile,
|
||||
sheet: string,
|
||||
cells: string
|
||||
): HTMLDivElement => {
|
||||
const sheetDiv = createDiv();
|
||||
|
||||
if (plugin.settings.showSheetButton == "true") {
|
||||
const fileEmbed = sheetDiv.createDiv({
|
||||
cls: "internal-embed file-embed mod-generic is-loaded",
|
||||
text: file.basename,
|
||||
attr: {
|
||||
src: file.basename,
|
||||
alt: file.basename,
|
||||
contenteditable: false,
|
||||
tabindex: -1,
|
||||
},
|
||||
});
|
||||
|
||||
// 点击按钮打开 sheet
|
||||
fileEmbed.onClickEvent((e) => {
|
||||
e.stopPropagation();
|
||||
plugin.app.workspace.getLeaf().openFile(file);
|
||||
});
|
||||
}
|
||||
|
||||
// <div class="internal-embed file-embed mod-generic is-loaded" tabindex="-1" src="Excel 2023-09-07 17.18.19.sheet" alt="Excel 2023-09-07 17.18.19.sheet" contenteditable="false"><div class="file-embed-title"><span class="file-embed-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-file"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg></span> Excel 2023-09-07 17.18.19.sheet</div></div>
|
||||
const fileEmbed = sheetDiv.createDiv({
|
||||
cls: "internal-embed file-embed mod-generic is-loaded",
|
||||
text: file.basename,
|
||||
var table = getExcelAreaHtml(excelData, sheet, cells);
|
||||
|
||||
var div = createDiv({
|
||||
cls: "sheet-html",
|
||||
attr: {
|
||||
src: file.basename,
|
||||
alt: file.basename,
|
||||
contenteditable: false,
|
||||
tabindex: -1
|
||||
tabindex: "-1",
|
||||
contenteditable: "false"
|
||||
}
|
||||
})
|
||||
div.appendChild(table)
|
||||
sheetDiv.appendChild(div);
|
||||
return sheetDiv;
|
||||
};
|
||||
|
||||
// 点击按钮打开 sheet
|
||||
fileEmbed.onClickEvent((e) => {
|
||||
e.stopPropagation()
|
||||
plugin.app.workspace.getLeaf().openFile(file)
|
||||
})
|
||||
/**
|
||||
* 预览模式下转换成 HTML 显示
|
||||
* @param data markdown 文件原始data
|
||||
* @param sheet sheet 名称
|
||||
* @param cells 选中的cells 格式为: sri-sci:eri-eci 例如 6-6:7-8
|
||||
* @returns
|
||||
*/
|
||||
const createSheetHtml = (
|
||||
data: string,
|
||||
file: TFile,
|
||||
sheet: string,
|
||||
cells: string
|
||||
): HTMLDivElement => {
|
||||
const sheetDiv = createDiv();
|
||||
|
||||
if (plugin.settings.showSheetButton == "true") {
|
||||
const fileEmbed = sheetDiv.createDiv({
|
||||
cls: "internal-embed file-embed mod-generic is-loaded",
|
||||
text: file.basename,
|
||||
attr: {
|
||||
src: file.basename,
|
||||
alt: file.basename,
|
||||
contenteditable: false,
|
||||
tabindex: -1,
|
||||
},
|
||||
});
|
||||
|
||||
// 点击按钮打开 sheet
|
||||
fileEmbed.onClickEvent((e) => {
|
||||
e.stopPropagation();
|
||||
plugin.app.workspace.getLeaf().openFile(file);
|
||||
});
|
||||
}
|
||||
|
||||
const sheetEl = createDiv({
|
||||
attr: {
|
||||
style: "overflow-x: auto;"
|
||||
},
|
||||
});
|
||||
|
||||
const table = getExcelAreaHtml(data, sheet, cells);
|
||||
sheetEl.appendChild(table);
|
||||
sheetDiv.appendChild(sheetEl);
|
||||
return sheetDiv;
|
||||
};
|
||||
|
||||
/**
|
||||
* bembed link 显示
|
||||
*/
|
||||
const createSheetEl = (
|
||||
data: string,
|
||||
file: TFile,
|
||||
width: number,
|
||||
height: number = 300
|
||||
): HTMLDivElement => {
|
||||
const sheetDiv = createDiv();
|
||||
|
||||
if (plugin.settings.showSheetButton == "true") {
|
||||
const fileEmbed = sheetDiv.createDiv({
|
||||
cls: "internal-embed file-embed mod-generic is-loaded",
|
||||
text: file.basename,
|
||||
attr: {
|
||||
src: file.basename,
|
||||
alt: file.basename,
|
||||
contenteditable: false,
|
||||
tabindex: -1,
|
||||
},
|
||||
});
|
||||
|
||||
// 点击按钮打开 sheet
|
||||
fileEmbed.onClickEvent((e) => {
|
||||
e.stopPropagation();
|
||||
plugin.app.workspace.getLeaf().openFile(file);
|
||||
});
|
||||
}
|
||||
// <div class="internal-embed file-embed mod-generic is-loaded" tabindex="-1" src="Excel 2023-09-07 17.18.19.sheet" alt="Excel 2023-09-07 17.18.19.sheet" contenteditable="false"><div class="file-embed-title"><span class="file-embed-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="svg-icon lucide-file"><path d="M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z"></path><polyline points="14 2 14 8 20 8"></polyline></svg></span> Excel 2023-09-07 17.18.19.sheet</div></div>
|
||||
|
||||
|
||||
const sheetEl = createDiv({
|
||||
cls: "sheet-iframe",
|
||||
attr: {
|
||||
id: `x-spreadsheet-${new Date().getTime()}`,
|
||||
style: `height: ${height}px`
|
||||
style: `height: ${height}px`,
|
||||
},
|
||||
});
|
||||
|
||||
const jsonData = JSON.parse(data || "{}") || {};
|
||||
// console.log("createSheetEl", jsonData, data)
|
||||
|
||||
// 设置 sheet 样式
|
||||
var style = {
|
||||
bgcolor: "#ffffff",
|
||||
align: "left",
|
||||
valign: "middle",
|
||||
textwrap: false,
|
||||
strike: false,
|
||||
underline: false,
|
||||
color: "#0a0a0a",
|
||||
font: {
|
||||
name: "Helvetica",
|
||||
size: 10,
|
||||
bold: false,
|
||||
italic: false,
|
||||
},
|
||||
};
|
||||
|
||||
if (plugin.settings.theme === "dark") {
|
||||
style = {
|
||||
bgcolor: "#363636",
|
||||
align: "left",
|
||||
valign: "middle",
|
||||
textwrap: false,
|
||||
strike: false,
|
||||
underline: false,
|
||||
color: "#e6e6e6",
|
||||
font: {
|
||||
name: "Helvetica",
|
||||
size: 10,
|
||||
bold: false,
|
||||
italic: false,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
//@ts-ignore
|
||||
const sheet = new Spreadsheet(sheetEl, {
|
||||
mode: "read",
|
||||
|
|
@ -186,23 +372,28 @@ const createSheetEl = (data: string, file: TFile, width: number, height: number
|
|||
showBottomBar: true,
|
||||
view: {
|
||||
height: () => height,
|
||||
width: () => width,
|
||||
width: () => width - 10,
|
||||
},
|
||||
row: {
|
||||
len: 100,
|
||||
len: parseInt(plugin.settings.defaultRowsLen),
|
||||
height: parseInt(plugin.settings.rowHeight),
|
||||
},
|
||||
col: {
|
||||
len: 26,
|
||||
len: parseInt(plugin.settings.defaultColsLen),
|
||||
width: parseInt(plugin.settings.colWidth),
|
||||
indexWidth: 60,
|
||||
minWidth: 60,
|
||||
},
|
||||
// @ts-ignore
|
||||
style: style,
|
||||
isDark: plugin.settings.theme === "dark",
|
||||
}).loadData(jsonData); // load data
|
||||
|
||||
updateSheetTheme(plugin.settings.theme === "dark");
|
||||
|
||||
// @ts-ignore
|
||||
sheet.validate();
|
||||
sheetDiv.appendChild(sheetEl)
|
||||
sheetDiv.appendChild(sheetEl);
|
||||
return sheetDiv;
|
||||
};
|
||||
|
||||
|
|
@ -262,7 +453,7 @@ const processInternalEmbed = async (
|
|||
internalEmbedEl: Element,
|
||||
file: TFile
|
||||
): Promise<HTMLDivElement> => {
|
||||
const src = internalEmbedEl.getAttribute("src");
|
||||
var src = internalEmbedEl.getAttribute("src");
|
||||
//@ts-ignore
|
||||
if (!src) return;
|
||||
|
||||
|
|
@ -272,16 +463,36 @@ const processInternalEmbed = async (
|
|||
|
||||
const data = await vault.read(file);
|
||||
|
||||
const alt = internalEmbedEl.getAttribute("alt") ?? "";
|
||||
|
||||
// 是否转换成HTML
|
||||
var toHTML = false;
|
||||
if (src.includes("{html}")) {
|
||||
toHTML = true;
|
||||
src = src.replace("{html}", "");
|
||||
}
|
||||
|
||||
var alt = internalEmbedEl.getAttribute("alt") ?? "";
|
||||
if (alt.includes("{html}")) {
|
||||
// 单 sheet 中的某一区域
|
||||
toHTML = true;
|
||||
alt = alt.replace("{html}", "");
|
||||
}
|
||||
|
||||
const split = src.split("#");
|
||||
var excelData = getExcelData(data);
|
||||
if (split.length > 1) {
|
||||
excelData = getExcelAreaData(
|
||||
data,
|
||||
split[1],
|
||||
alt
|
||||
);
|
||||
excelData = getExcelAreaData(data, split[1], alt);
|
||||
}
|
||||
|
||||
return await createSheetEl(excelData, file, internalEmbedEl.clientWidth);
|
||||
|
||||
// console.log('internalEmbedDiv', excelData, src, alt, toHTML)
|
||||
if (toHTML) {
|
||||
return await createSheetHtml(data, file, split[1], alt);
|
||||
} else {
|
||||
return await createSheetEl(
|
||||
excelData,
|
||||
file,
|
||||
internalEmbedEl.clientWidth
|
||||
);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ export default {
|
|||
|
||||
|
||||
// ExcelSettingTab.ts
|
||||
BASE_COLOR: "Base color scheme",
|
||||
BASE_COLOR_DESC: "Choose default color scheme",
|
||||
FILE_SETTING: "File Setting",
|
||||
FOLDER: "FOLDER",
|
||||
FOLDER_DESC: "Create files in this folder by default",
|
||||
|
|
@ -40,4 +42,10 @@ export default {
|
|||
ROW_HEIGHT_DESC: "Default row height",
|
||||
COLUMN_WIDTH: "Column Width",
|
||||
COLUMN_WIDTH_DESC: "Default column width",
|
||||
DEFAULT_ROWS_LEN: 'Default render rows',
|
||||
DEFAULT_ROWS_LEN_DESC: 'Default number of render rows',
|
||||
DEFAULT_COLS_LEN: 'Default render columns',
|
||||
DEFAULT_COLS_LEN_DESC: 'Default number of rendered columns',
|
||||
SHOW_SHEET_BUTTON: "Show Sheet Button",
|
||||
SHOW_SHEET_BUTTON_DESC: "Show Sheet Button",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@ export default {
|
|||
PLEASE_SELECT_DATA: "请选择要拷贝的数据",
|
||||
|
||||
IMPORT_XLSX_FILE: "导入 xlsx 文件",
|
||||
EXPORT_XLSX_FILE: "到处 xlsx 文件",
|
||||
EXPORT_XLSX_FILE: "导出 xlsx 文件",
|
||||
|
||||
// ExcelSettingTab.ts
|
||||
BASE_COLOR: "基础颜色",
|
||||
BASE_COLOR_DESC: "选择默认基础色",
|
||||
FILE_SETTING: "文件设置",
|
||||
FOLDER: "文件夹",
|
||||
FOLDER_DESC: "新建文件将放在此文件夹下",
|
||||
|
|
@ -39,4 +41,10 @@ export default {
|
|||
ROW_HEIGHT_DESC: "设置表格的默认行高",
|
||||
COLUMN_WIDTH: "列宽",
|
||||
COLUMN_WIDTH_DESC: "设置表格的默认列宽",
|
||||
DEFAULT_ROWS_LEN: '默认渲染行数',
|
||||
DEFAULT_ROWS_LEN_DESC: '创建表格时默认渲染最大行数',
|
||||
DEFAULT_COLS_LEN: '默认渲染列数',
|
||||
DEFAULT_COLS_LEN_DESC: '创建表格时默认渲染最大列数',
|
||||
SHOW_SHEET_BUTTON: "显示标题按钮",
|
||||
SHOW_SHEET_BUTTON_DESC: "是否显示标题按钮",
|
||||
};
|
||||
|
|
|
|||
17
src/main.ts
17
src/main.ts
|
|
@ -135,15 +135,22 @@ export default class ExcelPlugin extends Plugin {
|
|||
});
|
||||
};
|
||||
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("file-menu", fileMenuHandlerCreateNew),
|
||||
);
|
||||
|
||||
this.registerEvent(
|
||||
this.app.workspace.on("file-menu", fileMenuHandlerCreateNew),
|
||||
);
|
||||
|
||||
this.addCommand({
|
||||
id: "excel-autocreate",
|
||||
name: t("CREATE_EXCEL"),
|
||||
callback: () => {
|
||||
this.createAndOpenExcel(getExcelFilename(this.settings), undefined, this.getBlackData());
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
private registerMonkeyPatches() {
|
||||
const key =
|
||||
"https://github.com/zsviczian/obsidian-excalidraw-plugin/issues";
|
||||
"https://github.com/ljcoder2015/obsidian-excel";
|
||||
this.register(
|
||||
around(Workspace.prototype, {
|
||||
getActiveViewOfType(old) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { Notice } from "obsidian";
|
||||
import { t } from "../lang/helpers"
|
||||
import { expr2expr } from "../utils/alphabet"
|
||||
import { t } from "../lang/helpers";
|
||||
import { expr2expr } from "../utils/alphabet";
|
||||
import da from "src/lang/locale/da";
|
||||
/**
|
||||
* 获取 sheet 数据
|
||||
* @param data markdown 文件原始data
|
||||
|
|
@ -33,15 +34,6 @@ export const getExcelAreaData = (
|
|||
const excelData = getExcelData(data) || "{}";
|
||||
const jsonData = JSON.parse(excelData) || [];
|
||||
|
||||
var cellArray = cells.split(":");
|
||||
const start = cellArray[0].split("-");
|
||||
var sri = parseInt(start[0]); // 开始行
|
||||
var sci = parseInt(start[1]); // 开始列
|
||||
|
||||
const end = cellArray[1].split("-");
|
||||
var eri = parseInt(end[0]); // 结束行
|
||||
var eci = parseInt(end[1]); // 结束列
|
||||
|
||||
var newData = new Map<string, any>();
|
||||
|
||||
if (jsonData instanceof Array) {
|
||||
|
|
@ -49,15 +41,39 @@ export const getExcelAreaData = (
|
|||
return item.name === sheet;
|
||||
})[0];
|
||||
|
||||
newData.set("name", sheet);
|
||||
newData.set("autofilter", sheetData.autofilter);
|
||||
newData.set("freeze", sheetData.freeze);
|
||||
newData.set("styles", sheetData.styles);
|
||||
newData.set("validations", sheetData.validations);
|
||||
newData.set("merges", sheetData.merges);
|
||||
|
||||
var rowLen = eri - sri + 1;
|
||||
if (sheetData) {
|
||||
newData.set("name", sheet);
|
||||
newData.set("autofilter", sheetData.autofilter);
|
||||
newData.set("freeze", sheetData.freeze);
|
||||
newData.set("styles", sheetData.styles);
|
||||
newData.set("validations", sheetData.validations);
|
||||
newData.set("merges", sheetData.merges);
|
||||
|
||||
console.log("------", jsonData, cells, sheetData);
|
||||
var sri = 0;
|
||||
var sci = 0;
|
||||
var eri = 100;
|
||||
var eci = 26;
|
||||
|
||||
if (cells.includes(":")) {
|
||||
var cellArray = cells.split(":");
|
||||
const start = cellArray[0].split("-");
|
||||
var sri = parseInt(start[0]); // 开始行
|
||||
var sci = parseInt(start[1]); // 开始列
|
||||
|
||||
const end = cellArray[1].split("-");
|
||||
var eri = parseInt(end[0]); // 结束行
|
||||
var eci = parseInt(end[1]); // 结束列
|
||||
} else {
|
||||
if (sheetData.rows && sheetData.rows.len) {
|
||||
eri = sheetData.rows.len - 1;
|
||||
}
|
||||
if (sheetData.cols && sheetData.cols.len) {
|
||||
eci = sheetData.cols.len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
var rowLen = eri - sri + 1;
|
||||
// 用来存储新数据
|
||||
var rows = new Map<string, any>();
|
||||
// 解析 row,并重 0 开始排数据
|
||||
|
|
@ -75,10 +91,19 @@ export const getExcelAreaData = (
|
|||
if (cell) {
|
||||
// 如果当前cell是公式
|
||||
if (cell.text) {
|
||||
var text = cell.text as String
|
||||
if (text && text[0] === '=') {
|
||||
var text = cell.text as String;
|
||||
if (text && text[0] === "=") {
|
||||
// console.log('cell text', text, sri, sci)
|
||||
cell.text = text.replace(/[a-zA-Z]{1,3}\d+/g, word => expr2expr(word, -sci, -sri, (x, y) => true));
|
||||
cell.text = text.replace(
|
||||
/[a-zA-Z]{1,3}\d+/g,
|
||||
(word) =>
|
||||
expr2expr(
|
||||
word,
|
||||
-sci,
|
||||
-sri,
|
||||
(x, y) => true
|
||||
)
|
||||
);
|
||||
// console.log('update cell text', cell.text)
|
||||
}
|
||||
}
|
||||
|
|
@ -100,7 +125,7 @@ export const getExcelAreaData = (
|
|||
}
|
||||
// const rowLen = Math.max(9, eri - sri + 1)
|
||||
|
||||
console.log("rows", sheetData, rows);
|
||||
// console.log("rows", sheetData, rows);
|
||||
rows.set("len", rowLen);
|
||||
newData.set("rows", Object.fromEntries(rows));
|
||||
// const colLen = Math.max(Math.ceil(clientWidth / 91), eci - sci + 1)
|
||||
|
|
@ -115,3 +140,124 @@ export const getExcelAreaData = (
|
|||
// console.log("newData", Object.fromEntries(newData))
|
||||
return newJsonData;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取指定 sheet 中指定 cells 的数据转换成 HTML
|
||||
* @param data markdown 文件原始data
|
||||
* @param sheet sheet 名称
|
||||
* @param cells 选中的cells 格式为: sri-sci:eri-eci 例如 6-6:7-8
|
||||
* @returns
|
||||
*/
|
||||
export const getExcelAreaHtml = (
|
||||
data: string,
|
||||
sheet: string,
|
||||
cells: string
|
||||
): HTMLElement => {
|
||||
const excelData = getExcelData(data) || "{}";
|
||||
const jsonData = JSON.parse(excelData) || [];
|
||||
|
||||
var table = createEl("table");
|
||||
|
||||
if (jsonData instanceof Array) {
|
||||
const sheetData = jsonData.filter((item) => {
|
||||
return item.name === sheet;
|
||||
})[0];
|
||||
|
||||
if (sheetData) {
|
||||
var sri = 0;
|
||||
var sci = 0;
|
||||
var eri = 100;
|
||||
var eci = 26;
|
||||
if (cells.includes(":")) {
|
||||
var cellArray = cells.split(":");
|
||||
const start = cellArray[0].split("-");
|
||||
var sri = parseInt(start[0]); // 开始行
|
||||
var sci = parseInt(start[1]); // 开始列
|
||||
|
||||
const end = cellArray[1].split("-");
|
||||
var eri = parseInt(end[0]); // 结束行
|
||||
var eci = parseInt(end[1]); // 结束列
|
||||
} else {
|
||||
if (sheetData.rows && sheetData.rows.len) {
|
||||
eri = sheetData.rows.len - 1;
|
||||
}
|
||||
if (sheetData.cols && sheetData.cols.len) {
|
||||
eci = sheetData.cols.len - 1;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log("getExcelAreaHtml", cells, sri, sci, eri, eci);
|
||||
|
||||
// 记录合并单元格数量
|
||||
var mergeMap: Map<string, boolean> = new Map();
|
||||
|
||||
for (var row = sri; row <= eri; row++) {
|
||||
var tr = createEl("tr");
|
||||
table.appendChild(tr);
|
||||
|
||||
for (var col = sci; col <= eci; col++) {
|
||||
// 获取当前行的数据
|
||||
const cells = sheetData.rows[`${row}`];
|
||||
if (cells) {
|
||||
// 如果当前行有数据
|
||||
// 获取单元格数据
|
||||
const cell = cells.cells[`${col}`];
|
||||
if (cell) {
|
||||
// 如果单元格有数据展示数据
|
||||
if (cell.merge) {
|
||||
// 是否有合并单元格的操作
|
||||
var mergeRow = cell.merge[0] + 1;
|
||||
var mergeCol = cell.merge[1] + 1;
|
||||
|
||||
// 记录合并的行跟列
|
||||
for (var r = 0; r < mergeRow; r++) {
|
||||
const index = `${row + r}-${col}`;
|
||||
mergeMap.set(index, true);
|
||||
|
||||
for (var c = 0; c < mergeCol; c++) {
|
||||
const index = `${row + r}-${col + c}`;
|
||||
mergeMap.set(index, true);
|
||||
}
|
||||
}
|
||||
|
||||
var td = createEl("td", {
|
||||
text: cell.text || "",
|
||||
attr: {
|
||||
rowspan: mergeRow,
|
||||
colspan: mergeCol,
|
||||
},
|
||||
});
|
||||
tr.appendChild(td);
|
||||
} else {
|
||||
// 无合并单元格直接添加
|
||||
var td = createEl("td", {
|
||||
text: cell.text || "",
|
||||
});
|
||||
tr.appendChild(td);
|
||||
}
|
||||
} else {
|
||||
// 添加空白单元格需要判断是否被合并了
|
||||
const index = `${row}-${col}`;
|
||||
if (!mergeMap.get(index)) {
|
||||
// 单元格没数据添加空白单元格 & 没有被合并单元格
|
||||
var td = createEl("td");
|
||||
tr.appendChild(td);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const index = `${row}-${col}`;
|
||||
// 添加空白单元格需要判断是否被合并了
|
||||
if (!mergeMap.get(index)) {
|
||||
// 单元格没数据添加空白单元格 & 没有被合并单元格
|
||||
var td = createEl("td");
|
||||
tr.appendChild(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
return table;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,7 +4,11 @@ export interface ExcelSettings {
|
|||
excelFilenameDateTime: string,
|
||||
sheetHeight: string,
|
||||
rowHeight: string,
|
||||
colWidth: string
|
||||
colWidth: string,
|
||||
theme: string,
|
||||
showSheetButton: string,
|
||||
defaultRowsLen: string,
|
||||
defaultColsLen: string,
|
||||
}
|
||||
|
||||
export const DEFAULT_SETTINGS: ExcelSettings = {
|
||||
|
|
@ -13,5 +17,9 @@ export const DEFAULT_SETTINGS: ExcelSettings = {
|
|||
excelFilenameDateTime: "YYYY-MM-DD HH.mm.ss",
|
||||
sheetHeight: "300",
|
||||
rowHeight: "25",
|
||||
colWidth: "100"
|
||||
colWidth: "100",
|
||||
theme: "light",
|
||||
showSheetButton: "true",
|
||||
defaultRowsLen: "100",
|
||||
defaultColsLen: "26",
|
||||
};
|
||||
|
|
|
|||
28
src/utils/ThemeUtils.ts
Normal file
28
src/utils/ThemeUtils.ts
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
export function updateSheetTheme(isDark: Boolean) {
|
||||
const root = document.documentElement;
|
||||
if (isDark) {
|
||||
root.style.setProperty('--sheet-iframe-background-color', "#363636")
|
||||
root.style.setProperty('--sheet-iframe-border-color', "#a5a0f8")
|
||||
root.style.setProperty('--sheet-toolbar-background-color', "#a5a0f8")
|
||||
root.style.setProperty('--sheet-toolbar-divider-color', "#a5a0f8")
|
||||
root.style.setProperty('--sheet-dropdown-content-background-color', "#857fe6")
|
||||
root.style.setProperty('--sheet-dropdown-content-color', "#dcdcdc")
|
||||
root.style.setProperty('--sheet-dropdown-title-color', "rgba(0,0,0,0.9)")
|
||||
root.style.setProperty('--sheet-menu-color', "#000")
|
||||
root.style.setProperty('--sheet-menu-active-background-color', "#bdb9f9")
|
||||
root.style.setProperty('--sheet-header-background-color', "#bdb9f9")
|
||||
root.style.setProperty('--sheet-checked-before', "#025492")
|
||||
} else {
|
||||
root.style.setProperty('--sheet-iframe-border-color', "#f5f6f7")
|
||||
root.style.setProperty('--sheet-iframe-background-color', "#fff")
|
||||
root.style.setProperty('--sheet-toolbar-background-color', "#f5f6f7")
|
||||
root.style.setProperty('--sheet-toolbar-divider-color', "#e0e2e4")
|
||||
root.style.setProperty('--sheet-dropdown-content-background-color', "#fff")
|
||||
root.style.setProperty('--sheet-dropdown-content-color', "rgba(0,0,0,0.9)")
|
||||
root.style.setProperty('--sheet-dropdown-title-color', "rgba(0,0,0,0.9)")
|
||||
root.style.setProperty('--sheet-menu-color', "#80868b")
|
||||
root.style.setProperty('--sheet-menu-active-background-color', "#fff")
|
||||
root.style.setProperty('--sheet-header-background-color', "#f8f8f9")
|
||||
root.style.setProperty('--sheet-checked-before', "#4b89ff")
|
||||
}
|
||||
}
|
||||
124
styles.css
124
styles.css
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue