見出し画像

ブックマークレットで始める業務改善<中級編>③ Excelへのコピペを一発で!

前回はこちら。

Webの情報をExcelに転記するルーチンワークはありますか? 意外と面倒なこの手の作業もブックマークレットで一発です!


今回のお題: Webページの情報を整形してユーザーに渡す

練習用のページを用意しました。

以下のように商品が並んでいます。

この表から、商品番号と価格を抜き出して、以下のようなExcelシートを作りたい、というのが今回のお題です。

皆さんならどうしますか? ひとつずつコピペしていく手もありますし、webページを全選択 → コピー → 値貼り付けして、整形していく手もあります。でもどちらも結構大変ですね。

そんなときはブックマークレットで一発です!🐶

<textarea>要素を作って、コピペ用の文字列を表示する

ユーザーに情報(整形結果)を渡すため、何らかの形で情報をwebページに表示させなければなりません。

そんなときは、<textarea>要素(改行できるテキスト入力欄)を使うのがお手軽です。<textarea>要素に整形した情報を表示できれば、ユーザーはそれを全選択(Ctrl + A) → コピー(Ctrl + C)して、Excelに貼り付けできます。

以下のようにプログラミングしていきます。
※ 2.と3.は逆でも良いです。

  1. <textarea>要素を作る

  2. <textarea>要素をHTML文書に追加する(prepend( )を使う)

  3. <textarea>要素の value に整形結果を入れる(改行は"\n"、タブは"\t")

今回はユーザーが触りやすいところに<textarea>要素を挿入するため、append( ) ではなく prepend( ) を使ってみましょう。

完成したブックマークレットは以下の通りです。動かしてみてください。また、prepend( )(6行目)の代わりに append( ) を使うとどうなるか試してみてください。

javascript:(function(){
	const textarea = document.createElement("textarea"); /* <textarea>要素を作成 */
	textarea.setAttribute("rows", "15"); /* 高さを決める属性を追加 */
	textarea.setAttribute("cols", "40"); /* 幅を決める属性を追加 */
	textarea.value = "商品番号" + "\t" + "価格";  /* 見出しを追加 */
	document.querySelector("body").prepend(textarea); /* <body>の先頭に挿入 */

	document.querySelectorAll("#flex-container div").forEach(function(e) {
		const product = e.querySelectorAll("p")[0].innerText.replace("商品番号: ", "");
		const price = e.querySelectorAll("p")[1].innerText.replace("価格: ", "").replace("円", "");
		textarea.value = textarea.value + "\n" + product + "\t" + price;
	});
})();
挿入される<textarea>要素

商品番号の桁数のばらつきのせいで表が崩れて見えますが、全選択(Ctrl + A) → コピー(Ctrl + C)してExcelに貼り付けたらきれいな表になります。

textarea.value に"\n"を入れると、そこで改行します。"\t"を入れるとそこにタブが入り、Excelにコピペしたときに列が分かれます。

「商品番号: 」や「価格: 」や「円」は不要なので replace( ) で消しています。

プログラムをよく読んで、何をやっているのか理解してください。分からないところがあれば過去の記事を見直してみましょう。

クリップボードにデータを直接入れる

上のブックマークレットでもグッと便利になりましたが、せっかくならコピーするところも自動化したいですね。

大丈夫です、JavaScriptならクリップボードへのコピーも可能です😎navigator.clipboard.writeText( ) 関数を使います。

javascript:(function(){
	const str = "こんにちは!";
	navigator.clipboard.writeText(str);
})();

ただしこの関数は注意点があります。この関数は、Webページにフォーカスが当たっている必要があります。デベロッパーツールだとwebページのフォーカスが外れてしまうのでうまく動きません。ブックマークレットに登録して、一度webページをクリックしてから、動かしてください。

navigator.clipboard.writeText( ) だけだと見た目の変化が無いため、ユーザーは正しく動いたのか良く分かりません。alert( ) でメッセージを出してあげると親切ですね。

ただし、以下のプログラムはうまく動きません。

javascript:(function(){
	const str = "こんにちは!";
	navigator.clipboard.writeText(str);
	alert("クリップボードにコピーしました。"); /* NG例 */
})();

navigator.clipboard.writeText( ) は非同期関数のため、クリップボードへのコピーが完了する前に先走って alert( ) が起動し、webページへのフォーカスが外れてしまうからです。

この場合、以下のように then( ) を使います。理解にはJavaScriptのやや高度な知識が必要になりますので、今は気にせず、コピペして使ってください。

javascript:(function(){
	const str = "こんにちは!";
	navigator.clipboard.writeText(str).then(() => {
		alert("クリップボードにコピーしました。");
	});
})();

では、navigator.clipboard.writeText( ) を使った練習問題をやりましょう。

この記事の前半でやったことを、<textarea>要素を作らず、クリップボードへのコピーで実現してください。ブックマークレットを動かしたら、あとはExcelを開いて Ctrl + Vすればいい感じの表で貼り付けられる、という状態を目指します。

解答例は蝶の下です。

解答例:

javascript:(function(){
	let str = "商品番号" + "\t" + "価格";

	document.querySelectorAll("#flex-container div").forEach(function(e) {
		const product = e.querySelectorAll("p")[0].innerText.replace("商品番号: ", "");
		const price = e.querySelectorAll("p")[1].innerText.replace("価格: ", "").replace("円", "");
		str = str + "\n" + product + "\t" + price;
	});

	navigator.clipboard.writeText(str).then(() => {
		alert("クリップボードにコピーしました。");
	});
})();

<textarea>要素を組み立てる必要が無くなった分、スッキリしましたね。

str という変数が初めて出てくるところ(「宣言」といいます)で、これまで使ってきた const ではなく let を使っています。これは str の中身を後で変えたいからです(str = str + ~~~ の行で)。const にすると「コンスタントな変数を変えようとしていますよ」というエラーが出ます。

今回のまとめ

  • <textarea>要素を作り、整形結果をユーザーに返すプログラムを作りました。様々な局面で応用が利くテクニックです。

  • prepend( ) で先頭に要素を追加できます。

  • navigator.clipboard.writeText( ) でクリップボードにコピーできます。


このシリーズのすべての記事は、こちらのマガジンにまとめています。

🐶スキしていただけると励みになります!


この記事が気に入ったらサポートをしてみませんか?