mirror of
https://github.com/ljcoder2015/obsidian-excel.git
synced 2026-07-22 08:30:28 +00:00
feat: 编辑模式部分引入
This commit is contained in:
parent
2dac3e3a49
commit
81a2f20af3
4 changed files with 134 additions and 34 deletions
|
|
@ -4,6 +4,7 @@ import Spreadsheet from "x-data-spreadsheet";
|
|||
import * as XLSX from "xlsx";
|
||||
import { stox, xtos } from "./utils/xlsxspread";
|
||||
import { VIEW_TYPE_EXCEL, FRONTMATTER } from "./constants";
|
||||
import { getExcelData } from "./utils/DataUtils";
|
||||
|
||||
export class ExcelView extends TextFileView {
|
||||
public plugin: ExcelPlugin;
|
||||
|
|
@ -37,18 +38,6 @@ export class ExcelView extends TextFileView {
|
|||
return this.data;
|
||||
}
|
||||
|
||||
getExcelData(): string {
|
||||
const tagText = "# Excel\n";
|
||||
const trimLocation = this.data.search(tagText);
|
||||
if (trimLocation == -1) return this.data;
|
||||
const excelData = this.data.substring(
|
||||
trimLocation + tagText.length,
|
||||
this.data.length
|
||||
);
|
||||
// console.log("trimLocation", trimLocation, excelData, this.data);
|
||||
return excelData;
|
||||
}
|
||||
|
||||
headerData() {
|
||||
return FRONTMATTER + "\n# Excel\n";
|
||||
}
|
||||
|
|
@ -117,8 +106,18 @@ export class ExcelView extends TextFileView {
|
|||
}
|
||||
|
||||
handleEmbedLink(e: Event) {
|
||||
if (this.file) {
|
||||
navigator.clipboard.writeText(`![[${this.file.path}]]`);
|
||||
const data = this.cellsSelected.sheet;
|
||||
const sri = this.cellsSelected.sri;
|
||||
const sci = this.cellsSelected.sci;
|
||||
const eri = this.cellsSelected.eri;
|
||||
const eci = this.cellsSelected.eci;
|
||||
|
||||
|
||||
// 格式 sri-sci:eri-eci
|
||||
if (this.file && data && sri && sci && eri && eci) {
|
||||
const link = `![[${this.file.basename}#${data.name}|${sri}-${sci}:${eri}-${eci}]]`
|
||||
console.log(this.file, link)
|
||||
navigator.clipboard.writeText(link);
|
||||
new Notice("Copy embed link to clipboard");
|
||||
} else {
|
||||
new Notice("Copy embed link failed");
|
||||
|
|
@ -137,9 +136,9 @@ export class ExcelView extends TextFileView {
|
|||
this.handleExportClick(ev)
|
||||
);
|
||||
|
||||
// this.embedLinkEle = this.addAction("link", "copy embed link", (ev) =>
|
||||
// this.handleEmbedLink(ev)
|
||||
// );
|
||||
this.embedLinkEle = this.addAction("link", "copy embed link", (ev) =>
|
||||
this.handleEmbedLink(ev)
|
||||
);
|
||||
|
||||
this.copyHTMLEle = this.addAction("file-code", "copy to HTML", (ev) =>
|
||||
this.copyToHTML()
|
||||
|
|
@ -179,7 +178,7 @@ export class ExcelView extends TextFileView {
|
|||
);
|
||||
|
||||
// 初始化 sheet
|
||||
const jsonData = JSON.parse(this.getExcelData() || "{}") || {};
|
||||
const jsonData = JSON.parse(getExcelData(this.data) || "{}") || {};
|
||||
|
||||
//@ts-ignore
|
||||
this.sheet = new Spreadsheet(this.sheetEle, {
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import {
|
|||
} from "obsidian";
|
||||
import ExcelPlugin from "./main";
|
||||
import Spreadsheet from "x-data-spreadsheet";
|
||||
import { getExcelData, getExcelAreaData } from "./utils/DataUtils";
|
||||
|
||||
let plugin: ExcelPlugin;
|
||||
let vault: Vault;
|
||||
|
|
@ -100,8 +101,17 @@ const tmpObsidianWYSIWYG = async (
|
|||
|
||||
internalEmbedDiv.empty();
|
||||
const data = await vault.read(file);
|
||||
|
||||
const src = internalEmbedDiv.getAttribute("src") ?? ""
|
||||
const alt = internalEmbedDiv.getAttribute("alt") ?? ""
|
||||
const split = src.split("#")
|
||||
var excelData = getExcelData(data)
|
||||
if (split.length > 1) {
|
||||
excelData = getExcelAreaData(data, split[1], alt, internalEmbedDiv.clientWidth)
|
||||
}
|
||||
console.log('internalEmbedDiv', excelData, src, alt)
|
||||
const sheetDiv = createSheetEl(
|
||||
getExcelData(data),
|
||||
excelData,
|
||||
internalEmbedDiv.clientWidth
|
||||
);
|
||||
if (markdownEmbed) {
|
||||
|
|
@ -121,6 +131,7 @@ const createSheetEl = (data: string, width: number): HTMLDivElement => {
|
|||
});
|
||||
|
||||
const jsonData = JSON.parse(data || "{}") || {};
|
||||
// console.log("createSheetEl", jsonData, data)
|
||||
//@ts-ignore
|
||||
const sheet = new Spreadsheet(sheetEle, {
|
||||
mode: "read",
|
||||
|
|
@ -137,18 +148,6 @@ const createSheetEl = (data: string, width: number): HTMLDivElement => {
|
|||
return sheetEle;
|
||||
};
|
||||
|
||||
const getExcelData = (data: string): string => {
|
||||
const tagText = "# Excel\n";
|
||||
const trimLocation = data.search(tagText);
|
||||
if (trimLocation == -1) return data;
|
||||
const excelData = data.substring(
|
||||
trimLocation + tagText.length,
|
||||
data.length
|
||||
);
|
||||
// console.log("trimLocation", trimLocation, excelData, this.data);
|
||||
return excelData;
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @param el
|
||||
|
|
@ -161,7 +160,7 @@ export const markdownPostProcessor = async (
|
|||
//check to see if we are rendering in editing mode or live preview
|
||||
//if yes, then there should be no .internal-embed containers
|
||||
const embeddedItems = el.querySelectorAll(".internal-embed");
|
||||
console.log("markdownPostProcessor", embeddedItems.length);
|
||||
// console.log("markdownPostProcessor", embeddedItems.length);
|
||||
if (embeddedItems.length === 0) {
|
||||
tmpObsidianWYSIWYG(el, ctx);
|
||||
return;
|
||||
|
|
@ -174,7 +173,7 @@ const processReadingMode = async (
|
|||
embeddedItems: NodeListOf<Element> | [HTMLElement],
|
||||
ctx: MarkdownPostProcessorContext
|
||||
) => {
|
||||
console.log("processReadingMode");
|
||||
// console.log("processReadingMode");
|
||||
//We are processing a non-excalidraw file in reading mode
|
||||
//Embedded files will be displayed in an .internal-embed container
|
||||
|
||||
|
|
|
|||
101
src/utils/DataUtils.ts
Normal file
101
src/utils/DataUtils.ts
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
import { Notice } from "obsidian";
|
||||
/**
|
||||
* 获取 sheet 数据
|
||||
* @param data markdown 文件原始data
|
||||
* @returns 去掉头部数据的 sheet data
|
||||
*/
|
||||
export const getExcelData = (data: string): string => {
|
||||
const tagText = "# Excel\n";
|
||||
const trimLocation = data.search(tagText);
|
||||
if (trimLocation == -1) return data;
|
||||
const excelData = data.substring(
|
||||
trimLocation + tagText.length,
|
||||
data.length
|
||||
);
|
||||
// console.log("trimLocation", trimLocation, excelData, this.data);
|
||||
return excelData;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取指定 sheet 中指定 cells 的数据
|
||||
* @param data markdown 文件原始data
|
||||
* @param sheet sheet 名称
|
||||
* @param cells 选中的cells 格式为: sri-sci:eri-eci 例如 6-6:7-8
|
||||
* @returns
|
||||
*/
|
||||
export const getExcelAreaData = (
|
||||
data: string,
|
||||
sheet: string,
|
||||
cells: string,
|
||||
clientWidth: number
|
||||
): string => {
|
||||
const excelData = getExcelData(data) || "{}";
|
||||
const jsonData = JSON.parse(excelData) || [];
|
||||
|
||||
var sri: number | null = null;
|
||||
var sci: number | null = null;
|
||||
var eri: number | null = null;
|
||||
var eci: number | null = null;
|
||||
|
||||
var cellArray = cells.split(":");
|
||||
const start = cellArray[0].split("-");
|
||||
sri = parseInt(start[0]);
|
||||
sci = parseInt(start[1]);
|
||||
|
||||
const end = cellArray[1].split("-");
|
||||
eri = parseInt(end[0]);
|
||||
eci = parseInt(end[1]);
|
||||
|
||||
var newData = new Map<string, any>();
|
||||
newData.set("name", sheet);
|
||||
newData.set("autofilter", {});
|
||||
newData.set("freeze", "A1");
|
||||
newData.set("styles", [{ "0": { bgcolor: "#fe0000" } }]);
|
||||
newData.set("validations", []);
|
||||
|
||||
if (jsonData instanceof Array) {
|
||||
const sheetData = jsonData.filter((item) => {
|
||||
return item.name === sheet;
|
||||
})[0];
|
||||
var rowLen = eri - sri + 1;
|
||||
if (sheetData && sri && sci && eri && eci) {
|
||||
var rows = new Map<string, any>();
|
||||
for (var row = 0; row <= eri - sri; row++) {
|
||||
const rowsData = sheetData.rows[`${row + sci}`];
|
||||
// console.log("getExcelAreaData", sheetData, rowsData, row + eri);
|
||||
var newCells = new Map<string, any>();
|
||||
if (rowsData) {
|
||||
var cellsData = new Map<string, any>();
|
||||
for (var col = 0; col <= eci - sci; col++) {
|
||||
const cell = rowsData.cells[`${col + sci}`];
|
||||
if (cell) {
|
||||
cellsData.set(`${col}`, cell);
|
||||
if (row == eri - sri && cell.merge) {
|
||||
rowLen = Math.max(
|
||||
rowLen,
|
||||
eri - sri + 1 + cell.merge[0]
|
||||
);
|
||||
console.log(rowLen);
|
||||
}
|
||||
}
|
||||
}
|
||||
newCells.set("cells", Object.fromEntries(cellsData));
|
||||
}
|
||||
rows.set(`${row}`, Object.fromEntries(newCells));
|
||||
}
|
||||
// const rowLen = Math.max(9, eri - sri + 1)
|
||||
|
||||
rows.set("len", rowLen);
|
||||
newData.set("rows", Object.fromEntries(rows));
|
||||
// const colLen = Math.max(Math.ceil(clientWidth / 91), eci - sci + 1)
|
||||
const colLen = eci - sci + 1;
|
||||
newData.set("cols", { len: colLen });
|
||||
} else {
|
||||
new Notice("Please first select the data to copy");
|
||||
}
|
||||
}
|
||||
|
||||
const newJsonData = JSON.stringify(Object.fromEntries(newData));
|
||||
// console.log("newData", Object.fromEntries(newData))
|
||||
return newJsonData;
|
||||
};
|
||||
|
|
@ -16,8 +16,9 @@
|
|||
/* Markdown 文档引入样式设置*/
|
||||
.sheet-iframe {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
height: 308px;
|
||||
background-color: var(--background-primary-alt);
|
||||
border: 5px solid #f5f6f7;
|
||||
}
|
||||
|
||||
ul.x-spreadsheet-menu {
|
||||
|
|
|
|||
Loading…
Reference in a new issue