これはなに
xlsから、必要なデータをきちんと取得する方法とそのコード
方法
csv出力 → node.js
理由
xlsのままだと、hiddenファイルや、日付の取り扱いなど、面倒で変換しなければならない項目が多すぎる。単純に見えているデータだけほしいのに、なぜこんなにも疲弊しなければならないのか。
そうだ。CSVにしよう。
手順
CSVで保存
何も考えることはなし。xlsのほしいシートを、すべてcsvで保存する。
コードで抽出する
当たり前のことだが、csvには全部のデータが入っている。
しかしありがちなことに、xlsにはデータのテーブルだけが入っているわけではない。
余計な説明が初めにつらつらと書いてあることが常である。なので、必要な部分だけ取得する。
package.jsonはおかないが、適宜 npm install のこと。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
// pick.js // エクセルデータをCSVに変換したデータから、必要な箇所を指定し、その必要なデータを抜き出す。 // node pick.js <対象ファイル> <開始地点> <終了セル> <抜き出す列...> <出力先> const columnMappings = { B: "No", C: "name", }; import Datastore from "nedb-promises"; import fs from "fs"; import iconv from "iconv-lite"; import { parse } from "csv-parse/sync"; const args = process.argv.slice(2); const [fileName, startCell, endCell, ...columnArgs] = args; const dbName = columnArgs.pop() const selectedColumns = columnArgs.map(col => col.toUpperCase()) function columnToIndex(col) { return col.split("").reduce((sum, char) => sum * 26 + (char.charCodeAt(0) - 65), 0); } function parseCellRange(cell) { const match = cell.match(/^([A-Z]+)(\d+)$/); if (!match) { console.error(`エラー: 無効なセル形式 - ${cell}`); process.exit(1); } return { col: columnToIndex(match[1]), row: parseInt(match[2], 10) - 1 } } const start = parseCellRange(startCell); const end = parseCellRange(endCell); const buffer = fs.readFileSync(fileName); const utf8Csv = iconv.decode(buffer, "Shift_JIS"); const records = parse(utf8Csv, { columns: false, skip_empty_lines: false }); const slicedData = records.slice(start.row, end.row + 1); const startColIndex = columnToIndex(startCell.match(/^([A-Z]+)/)[1]); const columnIndexes = selectedColumns .map(col => columnToIndex(col) - startColIndex) .filter(index => index >= 0 && index < slicedData[0].length); if (columnIndexes.length !== selectedColumns.length) { console.error("エラー: 指定された列が見つかりません。"); process.exit(1); } const pickedData = slicedData.map(row => Object.fromEntries( selectedColumns.map((col, i) => [columnMappings[col] || col, row[columnIndexes[i]]]) ) ); let pickedDataSorted = pickedData.sort((a,b)=>{ return a.No - b.No }) const db = Datastore.create({ filename: `./${dbName}.db`, autoload: true }); (async () => { try { await db.remove({}, { multi: true }) await db.loadDatabase() await db.insert(pickedDataSorted) } catch (err) { console.log(err) } })(); |
利用方法
1 |
node pick.js B1 D10 B C D dbname |