CoffeeScriptを使ったTips集 その1

Excelファイルを読み込む

コマンドラインでexcelモジュールをインストールします。

$ npm install excel

次のようなExcelファイルを読み込む場合を考えます。

distance.xlsx

Excelデータをxlsx形式で保存し(distance.xlsx)、以下のようなプログラムで読み込みます。

excel = require "excel"

excel "distance.xlsx", (err, rows) ->
  if err then throw err

  # 1行目
  header = rows[0]
  console.log header.join("\t")
  console.log "================"

  # 2行目以降
  for row in rows[1..]
    [station, distance] = row
    console.log "#{station}\t#{distance}"

【実行結果】

駅名    距離 (m)
================
上野    0
御徒町  600
秋葉原  1000
神田    700
東京    1300
有楽町  800
新橋    1100
浜松町  1200
田町    1500
品川    2200

メールを送信する

コマンドラインでnodemailerモジュールをインストールします。

$ npm install nodemailer

Gmailのアカウントを使ってメールを送信するには以下のようにします。

nodemailer = require "nodemailer"

transport = nodemailer.createTransport "SMTP",
  service: "Gmail"
  auth:
    user: "username@gmail.com" # Gmailのユーザ名
    pass: "password"           # パスワード

mailData =
  from   : "山田太郎 <username@gmail.com>"  # 送信元
  to     : "田中二郎 <tanaka@example.com>"  # 宛先
  subject: "テスト件名"
  text   : "テスト本文\n2行目\n3行目"

# メールを送信する
transport.sendMail mailData, (err, resp) ->
  if err
    console.log "送信失敗"
    throw err
  else
    console.log "送信完了"

  # メールサーバとの接続を切る
  transport.close()

Excelファイルを読み込んでメールを送信する

上の2つを組み合わせると、Excelファイル中のメールアドレスに一斉送信できます。

addresses.xlsx
Excelファイルの例(addresses.xlsx)

前述のexcelとnodemailerに加えて、sequentモジュールをインストールします。

$ npm install sequent

以下のプログラムは、1通ごとに本文を変えてメールを送信する例です。

excel      = require "excel"
nodemailer = require "nodemailer"
Sequent    = require "sequent"

# Gmail送信パラメータ
transport = nodemailer.createTransport "SMTP",
  service: "Gmail"
  auth:
    user: "username@gmail.com"  # Gmailのユーザ名
    pass: "password"            # パスワード

# すべてのメールに共通するパラメータ
mailData =
  from   : "山田太郎 <username@gmail.com>"  # 送信元
  subject: "Excelからのテスト"  # 件名

# Excelファイルを読み込む
excel "addresses.xlsx", (err, rows) ->
  if err then throw err

  # データを配列にまとめる
  persons = []
  for row in rows
    persons.push
      name : row[0]
      email: row[1]

  seq = new Sequent

  # 1件ずつメールを送信
  for person in persons
    # 宛先をセット
    mailData.to = person.email

    # 本文をセット
    mailData.text = "#{person.name}さん、こんにちは。"

    transport.sendMail mailData, do (person) -> (err, resp) ->
      if err
        console.log "送信失敗: #{person.email}"
        throw err
      else
        console.log "送信完了: #{person.email}"
      seq.done()

  seq.wait persons.length, ->
    console.log "すべて完了"
    transport.close()