mirror of
https://github.com/hangeol-chang/obsidian-csv-allinone.git
synced 2026-07-22 05:37:25 +00:00
commit
f97a1aa366
7 changed files with 196 additions and 62 deletions
147
README.md
147
README.md
|
|
@ -1,111 +1,158 @@
|
|||
# Obsidian CSV All-in-One
|
||||
|
||||
A plugin for handling `.csv` files, including creating, editing, and saving CSV data.
|
||||
|
||||
> A plugin for creating `.csv` files, modifying their data, saving them, and performing various CSV-related operations.
|
||||
----
|
||||
## Other Language Docs
|
||||
- [Korean](./docs/README.kr.md)
|
||||
- Maybe add more later...
|
||||
- maybe add later...
|
||||
|
||||
## Brief Notice & Description
|
||||
> This plugin is designed to work in conjunction with `dataviewjs`.
|
||||
> Its primary purpose is to create CSV files and add data to them.
|
||||
> This plugin is built with the assumption that you are using DataviewJS.
|
||||
> The main purpose of this plugin is to create CSV files and add data to them.
|
||||
|
||||
----
|
||||
## Examples
|
||||
### Using Obsidian Command
|
||||
#### Creating CSV File
|
||||
### With Obsidian Command
|
||||
#### Creating a CSV File
|
||||
|
||||
- Press `Ctrl + P` -> Search for 'Create CSV Table'
|
||||
Enter the required data as shown below and click Submit.
|
||||
- Ctrl + P -> search for 'Create CSV Table'
|
||||
Enter the required data and click Submit as shown below:
|
||||

|
||||
|
||||
#### Search CSV Files
|
||||
- UI is subject to updates.
|
||||
- Press `Ctrl + P` -> Search for 'Open CSV Explorer'
|
||||
- Move or delete CSV files.
|
||||
- UI modifications are planned
|
||||
- Ctrl + P -> search for 'Open CSV Explorer'
|
||||
- You can move or delete CSV files.
|
||||
|
||||

|
||||
|
||||
### Using dataviewjs
|
||||
### With DataviewJS
|
||||
|
||||
#### - View as Table
|
||||
#### - View as table
|
||||
- Source Code
|
||||
```dataviewjs
|
||||
```javascript
|
||||
const csvPlugin = app.plugins.plugins['csv-allinone'];
|
||||
|
||||
const fileName = "HouseKeeping/t/2025-01.csv";
|
||||
|
||||
csvPlugin.readCSV(app, fileName).then(res => {
|
||||
const headers = res.headers.map(item => item[0]);
|
||||
dv.table(headers, res.rows);
|
||||
let headers = []
|
||||
let defaultValues = {}
|
||||
for(const [key, value] of Object.entries(res.headers)) {
|
||||
headers.push(key)
|
||||
defaultValues[key] = ""
|
||||
}
|
||||
const columnLength = headers.length;
|
||||
|
||||
let rows = []
|
||||
for(const row of res.rows) {
|
||||
const newRow = [row[0].slice(5), ...row.slice(1)]
|
||||
rows.push(newRow);
|
||||
}
|
||||
dv.table(headers, rows);
|
||||
})
|
||||
```
|
||||
- Output
|
||||
- Result
|
||||

|
||||
|
||||
#### - Add New Data (Row)
|
||||
> Requires the `buttons` plugin.
|
||||
|
||||
#### - Add new data (row)
|
||||
> This feature uses the Buttons plugin.
|
||||
- Feature Description
|
||||
- Adds a row to a specific CSV file.
|
||||
- The data is not processed once read. If real-time updates are needed, you must wait for the file to update and read it again separately.
|
||||
- Default values can be entered.
|
||||
|
||||
- Source Code
|
||||
```dataviewjs
|
||||
```javascript
|
||||
const csvPlugin = app.plugins.plugins['csv-allinone'];
|
||||
const { createButton } = app.plugins.plugins["buttons"];
|
||||
|
||||
const fileName = "HouseKeeping/t/2025-01.csv";
|
||||
|
||||
const openCsvModal = async(app, headers, f) => {
|
||||
csvPlugin.openCsvInputModal(app, headers, f)
|
||||
const openCsvAppendModal = async(app, headers, f, defaults) => {
|
||||
csvPlugin.openCsvInputModal(app, headers, f, defaults)
|
||||
}
|
||||
|
||||
csvPlugin.readCSV(app, fileName).then(res => {
|
||||
const headers = res.headers.map(item => item[0]);
|
||||
let headers = []
|
||||
let defaultValues = {}
|
||||
for(const [key, value] of Object.entries(res.headers)) {
|
||||
headers.push(key)
|
||||
defaultValues[key] = ""
|
||||
}
|
||||
const columnLength = headers.length;
|
||||
|
||||
let rows = []
|
||||
for(const row of res.rows) {
|
||||
const newRow = [row[0].slice(5), ...row.slice(1)]
|
||||
rows.push(newRow);
|
||||
}
|
||||
|
||||
dv.table(headers, rows);
|
||||
// default values
|
||||
defaultValues['Date'] = moment(Date.now()).format('YYYY-MM-DD');
|
||||
defaultValues['Category'] = res.headers['Category'].options[0];
|
||||
defaultValues['Description'] = '-' ;
|
||||
|
||||
dv.span(
|
||||
createButton({
|
||||
app, el: this.container,
|
||||
args: { name: "open row input Modal", class: "" },
|
||||
args: {
|
||||
name: "open csv input modal",
|
||||
class: ""
|
||||
},
|
||||
clickOverride: {
|
||||
click: openCsvModal, params: [app, res.headers, fileName]
|
||||
click: openCsvAppendModal,
|
||||
params: [app, res.headers, fileName, defaultValues]
|
||||
}
|
||||
})
|
||||
)
|
||||
})
|
||||
```
|
||||
- Output
|
||||
- Result
|
||||

|
||||
|
||||
#### - Add New Column
|
||||
#### - Delete Existing Column
|
||||
#### - Add new column
|
||||
#### - Delete existing column
|
||||
|
||||
### Using Templater
|
||||
- I don’t use Templater, so I’m not familiar with it. Sorry!
|
||||
|
||||
### With Templater
|
||||
- I am not familiar with Templater, so I can't provide much detail. Apologies.
|
||||
|
||||
----
|
||||
## Usage/Features
|
||||
|
||||
----
|
||||
## APIs
|
||||
### Handle Files
|
||||
- `readCSV`
|
||||
- Parameters: `(app: App, fileName: string)`
|
||||
- Returns: `Promise<CSVTable | null>`
|
||||
> Reads the specified `fileName` and returns a `CSVTable`.
|
||||
### Handle File
|
||||
- readCSV
|
||||
- Parameters (app: App, fileName: string)
|
||||
- Return: Promise<CSVTable | null>
|
||||
> Takes a filename and returns the corresponding CSVTable.
|
||||
|
||||
- `saveCSV`
|
||||
- Parameters: `(app: App, fileName: string, table: CSVTable)`
|
||||
- Returns: `void`
|
||||
> Saves the given `CSVTable` data to the specified `fileName`.
|
||||
- saveCSV
|
||||
- Parameters (app: App, fileName: string, table: CSVTable)
|
||||
- Return: void
|
||||
> Saves the CSVTable data into the given file.
|
||||
|
||||
### CSVTable (Class)
|
||||
- Functions available in the class will be documented here.
|
||||
### CSVTable (class)
|
||||
-- Functions available within the class will be documented here.
|
||||
|
||||
## How It Works
|
||||
#### Header (type)
|
||||
|
||||
#### CSVRow (type)
|
||||
|
||||
#### CSVCellType (type)
|
||||
|
||||
|
||||
## How it Works
|
||||
When you create a CSV file using this plugin, two files are generated: `.csv` and `.csv.meta`.
|
||||
If you load an existing CSV file, a `.csv.meta` file is generated automatically.
|
||||
|
||||
If you load an existing CSV file, a `.csv.meta` file will be generated automatically.
|
||||
|
||||
The `.csv` file contains basic table data, while the `.meta` file stores metadata about the columns, such as their attributes. In the current version (`v0.1.0`), the `.meta` file only stores the type of each column, but future updates will include features like data/select values, validity constraints, and more.
|
||||
The CSV file contains basic table data, while the `.meta` file contains information about each column's attributes.
|
||||
Currently (v0.1.0), the `.meta` file only stores column types, but in the future, it will include additional data, such as select values or validity checks.
|
||||
|
||||
## Contributing
|
||||
Any form of contribution is welcome.
|
||||
Feel free to contribute however you'd like. Contributions are always welcome!
|
||||
|
||||
## License
|
||||
- MIT
|
||||
- MIT
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
# Obsidian CSV All-in-One
|
||||
|
||||
.csv 파일을 생성하고, 내부의 데이터를 수정하고 저장하는 등 csv 관련된 작업을 처리하기 위한 플러그인입니다.
|
||||
> .csv 파일을 생성하고, 내부의 데이터를 수정하고 저장하는 등 csv 관련된 작업을 처리하기 위한 플러그인입니다.
|
||||
----
|
||||
## Other Language Docs
|
||||
-[english](../README.md)
|
||||
|
|
@ -30,13 +29,26 @@
|
|||
|
||||
#### - view as table
|
||||
- 소스코드
|
||||
```dataviewjs
|
||||
```javascript
|
||||
const csvPlugin = app.plugins.plugins['csv-allinone'];
|
||||
|
||||
const fileName = "HouseKeeping/t/2025-01.csv";
|
||||
|
||||
csvPlugin.readCSV(app, fileName).then(res => {
|
||||
const headers = res.headers.map(item => item[0]);
|
||||
dv.table(headers, res.rows);
|
||||
let headers = []
|
||||
let defaultValues = {}
|
||||
for(const [key, value] of Object.entries(res.headers)) {
|
||||
headers.push(key)
|
||||
defaultValues[key] = ""
|
||||
}
|
||||
const columnLength = headers.length;
|
||||
|
||||
let rows = []
|
||||
for(const row of res.rows) {
|
||||
const newRow = [row[0].slice(5), ...row.slice(1)]
|
||||
rows.push(newRow);
|
||||
}
|
||||
dv.table(headers, rows);
|
||||
})
|
||||
```
|
||||
- 결과물
|
||||
|
|
@ -45,25 +57,52 @@ csvPlugin.readCSV(app, fileName).then(res => {
|
|||
|
||||
#### - add new data (row)
|
||||
> buttons 플러그인을 사용합니다.
|
||||
- 기능 설명
|
||||
- 특정 csv 파일에 row를 추가합니다.
|
||||
- 이미 읽힌 상태의 데이터를 가공하지 않습니다. 실시간 업데이트가 필요하다면, 별도로 파일 업데이트를 await하여 다시 파일을 읽어야합니다.
|
||||
- defaultValue를 입력할 수 있습니다.
|
||||
|
||||
- 소스코드
|
||||
```dataviewjs
|
||||
```javascript
|
||||
const csvPlugin = app.plugins.plugins['csv-allinone'];
|
||||
const { createButton } = app.plugins.plugins["buttons"];
|
||||
|
||||
const fileName = "HouseKeeping/t/2025-01.csv";
|
||||
|
||||
const openCsvModal = async(app, headers, f) => {
|
||||
csvPlugin.openCsvInputModal(app, headers, f)
|
||||
const openCsvAppendModal = async(app, headers, f, defaults) => {
|
||||
csvPlugin.openCsvInputModal(app, headers, f, defaults)
|
||||
}
|
||||
|
||||
csvPlugin.readCSV(app, fileName).then(res => {
|
||||
const headers = res.headers.map(item => item[0]);
|
||||
let headers = []
|
||||
let defaultValues = {}
|
||||
for(const [key, value] of Object.entries(res.headers)) {
|
||||
headers.push(key)
|
||||
defaultValues[key] = ""
|
||||
}
|
||||
const columnLength = headers.length;
|
||||
|
||||
let rows = []
|
||||
for(const row of res.rows) {
|
||||
const newRow = [row[0].slice(5), ...row.slice(1)]
|
||||
rows.push(newRow);
|
||||
}
|
||||
|
||||
dv.table(headers, rows);
|
||||
// default values
|
||||
defaultValues['Date'] = moment(Date.now()).format('YYYY-MM-DD');
|
||||
defaultValues['Category'] = res.headers['Category'].options[0];
|
||||
defaultValues['Description'] = '-';
|
||||
|
||||
dv.span(
|
||||
createButton({
|
||||
app, el: this.container,
|
||||
args: { name: "open row input Modal", class: "" },
|
||||
args: {
|
||||
name: "open csv input modal",
|
||||
class: ""
|
||||
},
|
||||
clickOverride: {
|
||||
click: openCsvModal, params: [app, res.headers, fileName]
|
||||
click: openCsvAppendModal,
|
||||
params: [app, res.headers, fileName, defaultValues]
|
||||
}
|
||||
})
|
||||
)
|
||||
|
|
@ -98,6 +137,12 @@ csvPlugin.readCSV(app, fileName).then(res => {
|
|||
### CSVTable (class)
|
||||
-- class에서 할 수 있는 함수들 작성해둘 것.
|
||||
|
||||
#### Header (type)
|
||||
|
||||
#### CSVRow (type)
|
||||
|
||||
#### CSVCellType(type)
|
||||
|
||||
|
||||
## How it work
|
||||
이 플러그인을 이용하여 csv 파일을 생성하면, .csv, .csv.meta의 두 파일을 생성하게 됩니다.
|
||||
|
|
|
|||
12
docs/example/2025-01.csv
Normal file
12
docs/example/2025-01.csv
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Date,Category,Item,Cost,Description
|
||||
2025-01-01,food,Burger,12,Lunch at fast food
|
||||
2025-01-02,cafe,Latte,5,Morning coffee
|
||||
2025-01-03,shopping,T-Shirt,25,Bought a new T-shirt
|
||||
2025-01-04,transportation & vehicle,Gas,40,Refueled the car
|
||||
2025-01-05,housing & utilities,Electricity Bill,60,Monthly electricity payment
|
||||
2025-01-06,culture & hobby,Movie Ticket,15,Watched a movie
|
||||
2025-01-07,food,Pizza,18,Dinner with friends
|
||||
2025-01-08,cafe,Americano,4,Afternoon coffee
|
||||
2025-01-09,shopping,Sneakers,80,New running shoes
|
||||
2025-01-10,transportation & vehicle,Bus Ticket,3,Public transportation fare
|
||||
2025-01-30,food,hamburger,10,yummy
|
||||
|
30
docs/example/2025-01.csv.meta
Normal file
30
docs/example/2025-01.csv.meta
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"Date": {
|
||||
"type": "stringData",
|
||||
"default": "1970-01-01"
|
||||
},
|
||||
"Category": {
|
||||
"type": "select",
|
||||
"default": "",
|
||||
"options": [
|
||||
"food",
|
||||
"cafe",
|
||||
"shopping",
|
||||
"transportation & vehicle",
|
||||
"housing & utilities",
|
||||
"culture & hobby"
|
||||
]
|
||||
},
|
||||
"Item": {
|
||||
"type": "string",
|
||||
"default": ""
|
||||
},
|
||||
"Cost": {
|
||||
"type": "number",
|
||||
"default": 0
|
||||
},
|
||||
"Description": {
|
||||
"type": "string",
|
||||
"default": "-"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 392 KiB After Width: | Height: | Size: 194 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 633 KiB After Width: | Height: | Size: 698 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 32 KiB |
Loading…
Reference in a new issue