Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9134

『このExcelのA列のファイルのB列の文字列をC列の文字列にしてクレメンス』

$
0
0

「ちな、7,000件な!」
さすがに手入力はやってられん。という事で、Node.js で自動化してみました

※ 完成品はこちら

テスト環境の下準備

Node.jsはインストール済みで
最低限のjs知識がある方を前提としています

最終的なディレクトリ構造はこんな感じを想定してます
image.png

プロジェクトの作成

任意のディレクトリを作成してnpm initしましょう
入力項目は任意で決めて大丈夫です

bash
mkdir excel-replaceer
cd excel-replaceer
npm init

モジュールのインストール

今回使用するモジュールはfsxlsxの2つです

fs : https://www.npmjs.com/package/fs
xlsx : https://www.npmjs.com/package/xlsx

bash
npm install fs
npm install xlsx

テスト用のExcelファイルの作成

読み込んでくるtest.xlsxファイルを作成します
今回はプロジェクト直下に/testというディレクトリを作成し
そこに読み込んでくるExcelファイルと置換するhtmlファイルを設置します

今回、Excelのデータ内容は下記の様な感じで作成します

ABC
1test01.htmldummytest01
2test02.htmldummytest02
3test03.htmldummytest03

テスト用のhtmlファイルの作成

今回のテストで置換するhtmlファイルを作成します
『A列』に記載がある通りの名前でhtmlを3つ作成してください
ディレクトリはExcelファイルと同様/test配下に保存します

htmlファイルの中身は任意で決めてもらえばよいですが、
今回は『B列』の「dummy」を置換するのでどこかしらにdummyを記述してください

test01~3.html
<!DOCTYPE html><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width, initial-scale=1.0"><title>dummy</title></head><body></body></html>

これでテストを行う為の下準備は完了です

モジュール作成

次は実際にExcelから情報を取得して、置換処理を行うまでの解説です

index.jsの作成

プロジェクト直下にindex.jsを作成してください
ここに実際の置換処理を書いていきます

node moduleの読み込み

下準備の段階でインストールを行ったfsxlsxを使用するので
この2つを呼び出して、いつでも使えるように変数に格納します

index.js
constxlsx=require('xlsx');constutils=xlsx.utils;constfs=require('fs');

utilsxlsxの機能の一つで、こちらも毎回呼び出す手間を省く為に
変数に格納しています
これでモジュールを使う準備ができました

Excelファイルの読み込み

Excelファイルの操作はxlsxモジュールを使用して行います

index.js
// 上部 略consttestX=xlsx.readFile('./test/test.xlsx');constsheet=testX.Sheets['Sheet1'];

readFileを使用することによってExcelファイルの読み込みができます
読み込んだExcelの内容をtextXに格納し、その中のSheet1の情報を
sheet変数に格納しています

セルの値を取得する為にはsheet['A1']というように
シート情報からセル名を指定して取得してきますが、
今回は入力されている範囲を取得して、ループを回してデータを取得します

範囲の取得

index.js
// 上部 略constrange=sheet['!ref'];constrangeN=utils.decode_range(range);

次にシートの記載がある範囲を取得します
先ほどシートの情報を格納したsheet変数から['!ref]を指定すると
範囲が取得できるので、こちらをrengeの変数に格納します
今回の場合、rangeには『A1:C2』が入っています

範囲を取得することはできましたが、今取得してきた範囲は
テキストデータになっている為、A列からC列までループ処理は回せません
これを解決するためにutilsを使用していきます

utilsdecode_range()を使用して、先ほどとってきたテキストデータの
範囲を渡してあげる事で、詳細な範囲データを返してくれます
これをrangeNに格納しています 中身は下記の様になっています

{s:{c:0,r:0},e:{c:2,r:1}}

それぞれ情報内容はこんな感じ

key情報
sスタートのセル情報
eエンドのセル情報
c列 (A, B, C ~~) の情報
r行 (0, 1, 2 ~~) の情報

この情報を利用すれば、ループ分を回して行数分実行したり
列分実行したり、全レコード分実行したりできます

今回は『B列』に元データ『C列』に変更後データがある状態を想定して作るので
行数分、置換が実行できれば良いことになります

ループ・置換処理

今回は『A列』に置換したいファイル名が記載されており
『B列』に変更前の文字列、『C列』に変更後の文字列が記載されているので
行数分、置換処理を実行すれば良いことになります

for文で行数分ループするようにしましょう

index.js
// 上部 略for(letr=rangeN.s.r;r<=rangeN.e.r;r++){letaddress=utils.encode_cell({c:0,r:r});letcell=sheet[address];}
for(letr=rangeN.s.r;r<=rangeN.e.r;r++)

rangeN.s.rのスタートの行番号から、
rangeN.e.rのエンドの行番号までループする処理を書きます

次にセルの情報を取得してきます
『A列』に置換したいファイル名が記載されているので
列のインデックス番号であるcc:0で固定して編集するファイルを取得しましょう

letaddress=utils.encode_cell({c:0,r:r});letcell=sheet[address];

utilsencode_cell()を使用することでcrのプロパティで
指定されたセルを、テキストベースに変換してくれます

let address = utils.encode_cell({c:0, r:0});
の場合は、addressに「A1」が入ります

これで、cellに『A列』のデータ(ファイル名)が入るように設定できました
指定のファイルを読み込んでみましょう

// fs.readFile([読み込むファイルのパス], [読み込む文字コード], [コールバック関数]); fs.readFile('./test/'+cell.v,'utf-8',(err,data)=>{// エラー処理if(err){console.log(`【 ${cell.v}】ファイル読み込みエラー`);throwerr;}});

ファイルの読み書きにはfsモジュールを使用します
ファイルの読み込みではreadFile()を使用します
上記のように、簡単なエラー処理も書いておきましょう
このコールバック関数内で、置換の処理を行っていきます
コールバック関数で渡しているdataには取得してきた内容が入っています

// 変更前の内容を取得letB_address=utils.encode_cell({c:1,r:r});letB_cell=sheet[B_address];// 変更後の内容を取得letA_address=utils.encode_cell({c:2,r:r});letA_cell=sheet[A_address];// 置換constbeforeTxt=data;constafterTxt=beforeTxt.replace(newRegExp(B_cell.v,"g"),A_cell.v);

今回は『B列』に変更前の文字列、『C列』に変更後の文字列が
入っていることがわかっているので、それぞれ『A列』の情報を
とってきた時と同様に、cプロパティを固定して情報を取ってきます

あとはおなじみのreplace()を使用して置換をおこない
afterTxtに格納しておきます

// fs.writeFile([書き込むファイルパス], [書き込む内容], コールバック関数)fs.writeFile('./test/'+cell.v,afterTxt,(err)=>{if(err){console.log(`【 ${cell.v}】ファイル置換エラー`);throwerr;}console.log(`【 ${cell.v}】success !`);});

最後にファイルの上書きを行っていきます
ファイルの書き込みにはwriteFile()を使用します
こちらにも簡単なエラー処理を書いてあげましょう

index.jsの完成形はこんな感じ

index.js
// モジュールのインストールconstxlsx=require('xlsx');constutils=xlsx.utils;constfs=require('fs');// エクセルファイルの読み込みconsttestX=xlsx.readFile('./test/test.xlsx');// シートの読み込みconstsheet=testX.Sheets['Sheet1'];// セルの範囲の取得constrange=sheet['!ref'];// console.log(range);// セルの範囲を数値化constrangeN=utils.decode_range(range);// ループ処理for(letr=rangeN.s.r;r<=rangeN.e.r;r++){// ファイル名取得letaddress=utils.encode_cell({c:0,r:r});letcell=sheet[address];// htmlの読み込みfs.readFile('./test/'+cell.v,'utf-8',(err,data)=>{// エラー処理if(err){console.log(`【 ${cell.v}】ファイル読み込みエラー`);throwerr;}// 置換処理// 変更前の内容を取得letB_address=utils.encode_cell({c:1,r:r});letB_cell=sheet[B_address];// 変更後の内容を取得letA_address=utils.encode_cell({c:2,r:r});letA_cell=sheet[A_address];// 置換constbeforeTxt=data;constafterTxt=beforeTxt.replace(newRegExp(B_cell.v,"g"),A_cell.v);// ファイルの上書きfs.writeFile('./test/'+cell.v,afterTxt,(err)=>{if(err){console.log(`【 ${cell.v}】ファイル置換エラー`);throwerr;}console.log(`【 ${cell.v}】success !`);});});}

これで処理は完成しました!

処理の実行

最後に下記で実行して置換が行われるか試してみてください

node index.js

Viewing all articles
Browse latest Browse all 9134

Trending Articles