年賀状の住所録をGoogleスプレッドシートで管理していて、そこからはがきの宛名面を縦書きで印刷したい。ところが、スプレッドシートにもGoogleドキュメントにも、はがきの宛名面を作る機能はありません。検索して出てくるのはプログラムの解説記事が中心で、どこに何を貼ればよいのか分かりにくいものばかりです。
この記事では、コードを2つのファイルに貼るだけで、住所録から縦書きの宛名面を表示して印刷できる方法を、手順どおりに説明します。郵便番号は日本郵便が決めている枠の位置に合わせ、住所の数字は漢数字にします。コードを使いたくない人向けの方法も最後に書きました。
(確認日:2026年10月17日。Googleスプレッドシート・Chrome)
先に結論
- スプレッドシートとドキュメントには、はがきの宛名面を作る機能はありません。
- 下のコード(2ファイル)を住所録に貼ると、メニュー「宛名印刷」から、はがきの大きさで縦書きの宛名を表示し、そのまま印刷できます。
- 郵便番号は、日本郵便の資料にある枠の位置(上から12mm・右から8mm)に合わせています。
- 初めて使うときに「このアプリは Google で確認されていません」と出ます。自分で貼ったコードなので、手順どおり進めて大丈夫です。
- はがきに印刷する前に、普通紙に試し印刷して、はがきを重ねて位置を確かめてください。プリンターによって数mmずれることがあります。
この方法が合う人・合わない人
- 合う人:住所録をすでにスプレッドシートで作っている/毎年少しずつ直して使いたい/年賀状ソフトを買いたくない。
- 合わない人:差出人も宛名面に印刷したい(このコードは宛名だけです。差出人は裏面に入れるか手書きにします)/コードを貼る作業がどうしても不安。→ 最後の「コードを使わない方法」へ。
1. 住所録を用意する
1行目(見出し)を、次の名前にします。並び順は自由で、使わない列はなくてもかまいません。
- 郵便番号:「100-0013」のように入力。先頭が0の番号(060-0001 など)は、0が消えないように、列を選んで[表示形式]→[数字]→[書式なしテキスト]にしておくと安心です(0が消えて6桁になっていても、コードが先頭に0を補います)。
- 住所1:都道府県から番地まで(例:東京都千代田区霞が関1-2-3)。
- 住所2:建物名・部屋番号(例:ハイツ山田101号室)。
- 氏名:名字と名前の間にスペースを1つ(例:山田 太郎)。
- 敬称:空なら「様」になります。「先生」「御中」なども書けます。
- 連名:同じ宛名に並べる人の名前だけ(例:花子)。名前の位置がそろうように並びます。
- 印刷:チェックボックス。チェックした行だけを印刷します。列ごとなければ、全員を印刷します。

2. コードを貼る
- 住所録のスプレッドシートで[拡張機能]→[Apps Script]を開きます。
- 「コード.gs」の中身をすべて消して、下の1つ目のコードを貼ります。
- 左の「ファイル」の[+]→[HTML]を選び、名前をAtenaにします(「.html」は自動で付きます)。
- Atena.html の中身をすべて消して、下の2つ目のコードを貼ります。
- 上の保存ボタン(フロッピーの形)を押します。
- スプレッドシートのタブに戻って、ページを再読み込みします。メニューの右端に「宛名印刷」が出ます。
1つ目:コード.gs
/** @OnlyCurrentDoc */
// スプレッドシートの住所録から、はがきの宛名面(縦書き)を印刷します。
function onOpen() {
SpreadsheetApp.getUi()
.createMenu('宛名印刷')
.addItem('はがきの宛名を表示', 'showCards')
.addToUi();
}
function showCards() {
const html = HtmlService.createTemplateFromFile('Atena');
html.rows = JSON.stringify(readRows());
SpreadsheetApp.getUi().showModalDialog(
html.evaluate().setWidth(760).setHeight(720), 'はがきの宛名');
}
// 1行目の見出しで列を探します:郵便番号・住所1・住所2・氏名・敬称・連名・印刷
function readRows() {
const values = SpreadsheetApp.getActiveSheet().getDataRange().getDisplayValues();
const head = values[0].map(h => String(h).trim());
const col = name => head.indexOf(name);
const c = {
zip: col('郵便番号'), a1: col('住所1'), a2: col('住所2'),
name: col('氏名'), title: col('敬称'), joint: col('連名'), print: col('印刷')
};
if (c.name < 0 || c.a1 < 0) {
throw new Error('1行目に「氏名」と「住所1」の見出しが必要です。');
}
const get = (row, i) => (i < 0 ? '' : String(row[i]).trim());
return values.slice(1)
.filter(row => get(row, c.name) !== '')
.filter(row => c.print < 0 || /^(TRUE|○|〇|1)$/i.test(get(row, c.print)))
.map(row => ({
zip: get(row, c.zip), a1: get(row, c.a1), a2: get(row, c.a2),
name: get(row, c.name), title: get(row, c.title) || '様', joint: get(row, c.joint)
}));
}
2つ目:Atena.html
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+JP:wght@500&display=block" rel="stylesheet">
<style>
@page { size: 100mm 148mm; margin: 0; }
body { margin: 0; font-family: 'Noto Serif JP', 'Noto Serif CJK JP', 'Yu Mincho', 'Hiragino Mincho ProN', serif; }
.bar { position: sticky; top: 0; background: #f1f3f4; padding: 10px 14px; font: 14px sans-serif; display: flex; gap: 12px; align-items: center; z-index: 1; }
.bar button { font-size: 14px; padding: 6px 16px; }
.cards { padding: 16px; display: flex; flex-wrap: wrap; gap: 16px; }
.card { position: relative; width: 100mm; height: 148mm; background: #fff; outline: 1px solid #ccc; overflow: hidden; }
.zip { position: absolute; top: 12mm; width: 5.7mm; height: 8mm; line-height: 8mm; text-align: center; font-size: 5.6mm; font-family: sans-serif; }
.v { position: absolute; writing-mode: vertical-rl; text-orientation: upright; white-space: nowrap; }
.a1 { right: 9mm; top: 25mm; font-size: 5mm; }
.a2 { right: 17mm; top: 33mm; font-size: 5mm; }
.names { position: absolute; top: 30mm; left: 50%; transform: translateX(-50%); display: flex; flex-direction: row-reverse; gap: 2mm; }
.names .v { position: static; font-size: 9mm; letter-spacing: 0.08em; }
@media print {
.bar { display: none; }
.cards { padding: 0; display: block; }
.card { outline: none; break-after: page; }
}
</style>
</head>
<body>
<div class="bar"><span id="count"></span><button id="print">印刷する</button>
<span>用紙:はがき/倍率:100%(実際のサイズ)/余白:なし</span></div>
<div class="cards" id="cards"></div>
<script>
const rows = <?!= rows ?>;
// 郵便番号の枠(日本郵便の仕様:上端から 12mm・右端から 8mm、枠 5.7×8mm)
const ZIP_LEFT = [0, 7, 14, 21.6, 28.4, 35.2, 42].map(x => 100 - 8 - 47.7 + x);
const KANJI = '〇一二三四五六七八九';
const DIGITS = '01234567890123456789';
// 縦書き用に、数字を漢数字に、ハイフンを縦の棒(ー)にする
function tate(s) {
return s.replace(/[0-90-9]/g, d => KANJI[DIGITS.indexOf(d) % 10]).replace(/[--‐―−ー]/g, 'ー');
}
function zipDigits(z) {
let d = z.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) - 0xFEE0)).replace(/\D/g, '');
if (d.length === 6) d = '0' + d; // 先頭の 0 が消えた番号
return d.length === 7 ? d : '';
}
function el(cls, text, parent) {
const e = document.createElement('div'); e.className = cls; e.textContent = text; parent.appendChild(e); return e;
}
// 長すぎる行は、はがきに収まるまで文字を小さくする
function fit(e, maxMm) {
const mm = px => px / 96 * 25.4;
let size = parseFloat(getComputedStyle(e).fontSize);
while (mm(e.getBoundingClientRect().height) > maxMm && size > 8) { size -= 0.5; e.style.fontSize = size + 'px'; }
}
function render() {
const box = document.getElementById('cards');
rows.forEach(r => {
const c = document.createElement('div'); c.className = 'card'; box.appendChild(c);
zipDigits(r.zip).split('').forEach((d, i) => { const z = el('zip', d, c); z.style.left = ZIP_LEFT[i] + 'mm'; });
fit(el('v a1', tate(r.a1), c), 112);
if (r.a2) fit(el('v a2', tate(r.a2), c), 104);
const names = document.createElement('div'); names.className = 'names'; c.appendChild(names);
el('v', tate(r.name) + ' ' + r.title, names);
if (r.joint) {
// 連名は、名字の分だけ下げて名前の位置をそろえる
const family = r.name.split(/[ ]/)[0];
const j = el('v', '', names);
const pad = document.createElement('span'); pad.style.visibility = 'hidden'; pad.textContent = tate(family) + ' ';
j.append(pad, tate(r.joint) + ' ' + r.title);
}
names.querySelectorAll('.v').forEach(v => fit(v, 108));
});
document.getElementById('count').textContent = rows.length + ' 枚';
}
// 文字の形が決まってから大きさを合わせる
document.fonts.load('20px "Noto Serif JP"', '東京都山田様').catch(() => {}).then(render);
document.getElementById('print').onclick = () => window.print();
</script>
</body>
</html>
3. 初めて使うときの許可
[宛名印刷]→[はがきの宛名を表示]を選ぶと、最初の1回だけ許可を求められます。
- 「承認が必要です」→[権限を確認]を押し、自分のGoogleアカウントを選びます。
- 「このアプリは Google で確認されていません」と出たら、左下の[詳細]→[(プロジェクト名)(安全ではないページ)に移動]を押します。
- 許可する内容は2つだけです。「このアプリケーションがインストールされているスプレッドシートの表示と管理」(=この住所録だけ)と、「Google アプリケーション内のプロンプトとサイドバーで…表示、実行」(=はがきの画面を出すため)。[すべて選択]にチェックして[次へ](または[続行])を押します。

この警告は、Googleの審査を受けていない自作のコードが、画面(ダイアログ)を出す権限を求めるときに出るものです。上のコードは、開いている住所録を読むことと、はがきの画面を出すことしかしません。住所録を書き換えたり、外に送ったりする部分はありません。
4. 表示して印刷する
- [宛名印刷]→[はがきの宛名を表示]を選びます。はがきの大きさで、1人1枚ずつ表示されます。
- [印刷する]を押します。
- 印刷の画面で、プリンターを選び、用紙サイズを「はがき」にします。倍率は100%(実際のサイズ)のままにし、「ページに合わせる」などの縮小はしません。
- まず普通紙に1枚だけ印刷し、はがきを重ねて、郵便番号が枠に入っているかを確かめます。
- ずれていなければ、はがきをプリンターにセットして印刷します(はがきの向き・表裏はプリンターの説明書に従ってください)。

郵便番号と住所の位置の決め方
郵便番号の数字は、日本郵便の「郵便番号・バーコードマニュアル」にある枠の寸法(郵便番号枠)に合わせて置いています。はがきの上から12mm、右から8mmの位置に、幅5.7mm・高さ8mmの枠が7つ並ぶ、という寸法です。

- 住所の数字は漢数字に(1-2-3 → 一ー二ー三、101 → 一〇一)、ハイフンは縦の棒にします。縦書きで数字が横に寝ないようにするためです。
- 住所や名前が長すぎるときは、はがきに収まるまで文字を自動で小さくします。小さくなりすぎるときは、建物名を「住所2」に分けてください。
- 名前は中央、住所は右側、建物名はその左に、一段下げて置いています。
注意すること
- 開いているシートの住所録を読みます。別のシートを開いたまま実行すると「見出しが必要です」と出ます。
- 郵便番号が7桁でない行は、郵便番号を空けて印刷します(6桁は先頭の0を補います)。
- 英字(例:Aハイツ)は1文字ずつ縦に並びます。
- 差出人は印刷されません。裏面のデザインに入れるか、手書きにしてください。
- スマホのアプリでは、コードで追加したメニューは出ません。パソコンのブラウザで使ってください。
- プリンターの紙送りで数mmずれることがあります。試し印刷でずれが分かったら、はがきの入れ方を見直してください。
コードを使わない方法
コードを貼るのが不安な場合は、スプレッドシートの住所録を[ファイル]→[ダウンロード]→[カンマ区切り形式(.csv)]で書き出し、住所録を読み込める年賀状ソフトやWebサービスで宛名を作る方法があります。たとえばブラザーの無料サービス「Web年賀状キット2027」は、ソフトのインストールなしでブラウザから宛名を作れ、毎年の住所録を流し込んで使えると案内されています(ブラザー公式)。読み込めるCSVの形式は、各サービスの説明を確認してください。
よくある質問
Googleドキュメントで縦書きの宛名は作れますか?
2026年10月時点で、Googleドキュメントには縦書きの機能がありません。この記事の方法は、はがきの画面をブラウザで作って印刷する仕組みなので、ドキュメントを使いません。
Excelの住所録でも使えますか?
Excelのファイルをスプレッドシートで開くか、[ファイル]→[インポート]で読み込めば使えます。1行目の見出しを、この記事の名前にそろえてください。
「印刷」の列はなくてもいいですか?
なくても動きます。その場合は、氏名が入っている行をすべて印刷します。
喪中はがきや寒中見舞いにも使えますか?
宛名面は同じなので使えます。敬称の列で「様」以外にも変えられます。
⚡ いま読まれているトレンド
ドコモ「あんしんフィルター」の障害が続く|設定が変えられない・アプリが使えないときの対処(Androidは窓口で暫定案内、iPhoneはプロファイル削除)
日本シリーズ2026はどこで見られる?|第2戦〜第7戦のテレビ(TBS・NHK BS・日テレ・テレ朝)とネット配信(TVer・U-NEXT・Hulu・ABEMA)
DEAN & DELUCAのチャリティートートバッグ2026|先行販売の抽選は10月29日17時まで、発売は11月1日。アプリでのエントリーと当日の時間










コメント