見出し画像

複数の予定をカレンダーに一括登録する方法

やりたいこと

 Excel 等で作成した予定を、一括でAppleのカレンダーアプリに登録する方法をググってみたら、CSV 形式のものを一度 Google カレンダーに 一括インポートして、それをエクスポートしたものをAppleカレンダーに読み込ませるとあった。
 そこで、1行目に項目識別のキーワードを入れた次のような表を作って CSV に書き出した。

Excelで作成した予定のリスト

これをCSV形式で保存すると、こんな感じになります。

Subject,Start Date,Start Time,End Date,End Time
出勤,2023/2/10,9:00,2023/2/10,15:00
出勤,2023/2/11,10:00,2023/2/1,16:00
出勤,2023/2/12,9:00,2023/2/12,15:00

ところがGoogle カレンダーへのインポートできず!

ググった記事には CSV 形式でインポートできるとあったが、できなくなったみたい。iCal または VCS形式ならインポートできると書いてあった! (それ以外は受け付けない)

Google Calendar のインポートのダイアログ

CSV を iCal に変換しよう!

 せっかく作った CSV データを iCal 形式に変換する方法を探してみたら、次のサイトがありました。
https://csv-to-ical.chimbori.com/
早速試してみると、ちゃんと Appleカレンダー、Googleカレンダーのどちらにも一括登録できるデータが出来上がりました。

プログラマの血が騒いで、自分で作ってみた

 上記の手順で、当初の目的は果たせましたが、プログラマの血が騒いで、変換プログラムを作ってみたくなった。(笑)
 JavaScript に CSV 形式をパースするライブラリもありますが、データの配列順を変えない前提で、通常のテキストとして単純に処理するようにしました。(1行目のデータは無視(笑))
ということで、 GUI をHTMLで、 処理の部分をJavaScript で行うやり方で、単一ファイルの Webアプリとしました。

<!doctype html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>CSV to iCalコンバータ</title>
</head>

<body>
<h3>CSV to iCal コンバータ</h3>
<div>
	<h3>変換前</h3>
	<form name="inputForm">
		<input name="inFile" type="file" /><br />
		<textarea name="inData" cols="80" rows="10"></textarea>
	</form>
	<h3>変換後</h3>
	<form name="outForm">
		<textarea name="outData" cols="80" rows="20"></textarea>
		<a id="btn" download="iCal.ics">ダウンロード</a>
	
	</form>
</div>
<script type="module">
	var form = document.forms.inputForm;
	form.inFile.addEventListener( 'change', function(e) {
		const result = e.target.files[0];
		const reader = new FileReader();
		reader.readAsText( result );
		reader.addEventListener( 'load', function() {
			form.inData.textContent = reader.result;
			document.forms.outForm.outData.textContent = conv(reader.result.split("\r"));	// 改行コードに注意
		})
	})
	var conv = function(csv) {
		let iCal = "BEGIN:VCALENDAR\r";
		iCal += "VERSION:2.0\r";
		iCal += "CALSCALE:GREGORIAN\r";
		iCal += "X-WR-CALNAME;VALUE=TEXT:iCal\r";
        for (let i = 1; i < csv.length; ++i) {    // 1行目を無視
			let cells = csv[i].split(",");
			if (cells.length != 1) {
				let event = makeEvent(cells);
				iCal += event;
			}
		}
		
		iCal = iCal + "END:VCALENDAR\r";
		return iCal;
	}
	var makeEvent = function(cells) {
		let ev = "BEGIN:VEVENT\r";
		ev += "SUMMARY:" + cells[0] + "\r";
		ev += "DTSTAMP:" + dateConv(cells[1]) + "T" + timeConv(cells[2]) + "\r";
		ev += "DTSTART:" + dateConv(cells[1]) + "T" + timeConv(cells[2]) + "\r";
		ev += "DTEND:" + dateConv(cells[3]) + "T" + timeConv(cells[4]) + "\r";
		
		ev += "END:VEVENT\r";
		return ev;
	}
	var dateConv = function(dateIn) {
		const dw = dateIn.split("/");
		return dw[0] +  ("0" + dw[1]).substr(-2) +  ("0" + dw[2]).substr(-2)
	}
	var timeConv = function(timeIn) {
		const tw = timeIn.split(":");
		return ("0" + tw[0]).substr(-2) + ("0" + tw[1]).substr(-2) + "00";
	}

</script>

<script type="module">
	const btn = document.getElementById('btn');
	console.log("btn");
	btn.addEventListener('click', function() {
		const blob = new Blob([document.forms.outForm.outData.textContent], {"type": "text/plain"});
		btn.href = window.URL.createObjectURL(blob);
	})
</script>

</body>
</html>

使い方

 上記のソースをHTML拡張子を付けて保存し、そのファイルを Web ブラウザーで開いて、「ファイルを選択」で csv 形式のデータを開くと、すぐに iCal データに変換します。あとは「ダウンロード」すれば、テキストファイルとして保存されます。

使用上の注意

 macOS で動作していますが、Windows だと、文字コード、改行コードが違って正常に動作しないかもしれません。その際は適当に JavaScript を修正してお使いください。
また、冒頭で書いているようにデータの並びに依存していますので、それに合わせてください。

いいなと思ったら応援しよう!