💸

確定申告の外国税額控除のためにウェルスナビのPDFをparseしてみた

2022/03/08に公開

はじめに

確定申告には外国税額控除というものがある。

確定申告の外国税額控除画面

私はウェルスナビを使っているのだが、ウェルスナビ発行のPDFを見ながら外国税額控除を入力するのが面倒だったので、(3つくらい入力して慣れれば別にそうでもない説あり)

  • 全てのPDFを全部parseして入力に必要なものをCSVとして出力し、
  • その項目をコピーして各項目にペースト

をやってみることにした。

parseしてみる

ウェルスナビのPDF

PDFをparseすると、テキスト部分は配列となって取得出来る。
まず、数ファイルを1ファイルずつparseして見比べてみて、テキスト部分の配列とウェルスナビのPDFの項目の対応を出してみる。
今回はPDF.jsを利用した。

// node v17.0.1

const fs = require('fs');

// "pdfjs-dist": "^2.13.216"
const pdfjsLib = require("pdfjs-dist/legacy/build/pdf");

async function GetTextFromPDF(path, pageNumber) {
    let doc = await pdfjsLib.getDocument(path).promise;
    let page = await doc.getPage(pageNumber);
    let content = await page.getTextContent();
    let strings = content.items.map(function(item) {
        return item.str;
    });
    return strings;
}

// PDFファイルはpdfディレクトリに置いてある
let path = 'pdf/2020210105.pdf';
GetTextFromPDF(path, 1).then(data => data.forEach((v, i) => console.log(`i: ${i}, v: ${v}`)));
配列index データ例 ウェルスナビPDF対応箇所 確定申告入力欄対応箇所
0 (00000-0878-1) 7
1 銘柄
2 連 絡 先
3 T E L
4 権利区分
5
6 通貨区分
7
8 支払方法
9
10 現地支払日
11 国内支払日
12 残高基準日
13 2021年01月06日 6 4, 5
14 お預り数量
15
16 現地税込金額
17
18 現地源泉税率
19
20 現地源泉税額
21
22 現地税引き後金額
23 単位当りの
24 2020年12月28日 5
25 支払基準日
26
27 支払レート
28 部店
29
30 扱者
31
32 口座番号
33 123 1
34
35 456 2
36
37 1234567 3
38
39 苗 字 4
40
41 名 前 4
42
43
44 国内税引き前金額
45
46 上段:外貨
47 下段:円貨
48 国内源泉所得税額
49
50 お受取り金額
51 上段:外貨
52 (下記Aより)
53 国内源泉住民税額
54 (下記Bより)
55 下段:円貨
56 上段:外貨
57 下段:円貨
58 上段:外貨
59 下段:円貨
60 [国内源泉税額の計算明細 及び 申告用明細]
61 現地源泉税率
62 源泉徴収レート
63
64 国内課税対象金額(円貨)
65 源泉徴収レート・・・現地保管機関が配当等を受領した日又は
66 権利の確定ごとに公表される現地支払開始日の為替レート
67 A:国内源泉所得税額(円貨)
68
69 B:国内源泉住民税額(円貨)
70 源泉徴収基準日
71 (申告円換算日)
72 制限税率
73 (USD)
74
75 還付請求金額(外貨)
76 2020-12-30 24
77
78 103.25 25
79
80 0.7818 13
81 Vanguard 7
82
83 VTI 7
84
85 ETF 7
86
87 配当金 8 2
88
89 米ドル 9 10, 13
90
91 円貨払い 10
92
93 2020-12-30 24
94 65.433 12
95 配当金
96 51.15 14? 9
97
98 10.00% 15?
99
100 5.12 16 12
101
102 46.03 17
103 2021-01-04 18
104
105 103.12 19
106 <ご説明>
107
108 為替レートについて
109 ② 支払レート
110
111 ・・・弊社が配当等の受領を確認した日の為替レート又は、予約為替レート
112 4,746 20
113 内容をご確認のうえ、ご不明の点がございましたら、すみやかに弊社連絡先まで直接ご連絡ください。
114 727 21?
115
116 237 22?
117
118 3,782 23
119 お 客 様 サ ポ ー ト
120 4,752 26
121
122 0.00 29
123 727 27?
124
125 237 28?
126 現地課税対象金額(外貨)
127
128 現地税込金額(円貨)
129 現地税込金額(外貨)×源泉レート
130
131 外税控除の対象となる金額
132 10.00% 30?
133 0 3 - 6 6 3 2 - 9 5 7 8
134 10.00% 31?
135 2021年01月05日
136 (外貨)
137 51.15 32?
138 (通貨コード)
139 (外貨)
140
141 (外貨)
142 (外貨)
143 作成
144 (銘柄コード)
145 (USD)
146 (USD)
147 5,281 33 11
148
149 528 34 14
150 外国証券
151
152 利金・分配金・償還金・配当金等のお知らせ
  • PDF上で同じ数字が入っている欄は見分けが付かないため ? としている
  • 自分の2021年分のPDFは、parseすると配列長が全て同じだった。奇跡的に銘柄名も「Vanguard VTI ETF」、「Vanguard VWO ETF」のように全て3単語で構成されていた

CSVにする

上記で確定申告で使えるテキスト配列のindexが分かったので、その部分をCSVとして出力する。区切り文字はタブ文字で。

const fs = require('fs');

const pdfjsLib = require("pdfjs-dist/legacy/build/pdf");


async function GetTextFromPDF(path, pageNumber) {
    let doc = await pdfjsLib.getDocument(path).promise;
    let page = await doc.getPage(pageNumber);
    let content = await page.getTextContent();
    let strings = content.items.map(function(item) {
        return item.str;
    });
    return strings;
}

fs.readdir('pdf', (err, files) => {
    files.forEach(async file => {
        // PDFファイルはpdfディレクトリ配下に置いてある
        let doc = await pdfjsLib.getDocument(`pdf/${file}`).promise;
        for (let i = 1; i <= doc.numPages; i++) {
            GetTextFromPDF(`pdf/${file}`, i).then(data => {
                console.log(
                    [
                        data[13],
                        data[87],
                        data[89],
                        data[96],
                        data[100],
                        data[147],
                        data[149]
                    ].join('\t')
                );
            });
        }
    });
});
result
2021年01月06日  配当金  米ドル  51.15   5.12    5,281   528
2021年02月10日  配当金  米ドル  3.01    0.30    317     31
2021年03月10日  配当金  米ドル  3.18    0.32    344     34
.
.

おわりに

ほんの少しだけ入力が楽になった気はするが、人間が手入力すると入力ミスが発生する可能性がある。
そもそも、確定申告書作成コーナーがXML等を読み込ませて自動入力出来るように進化して欲しい。そしてウェルスナビ等がそのXMLを提供して欲しい。

その他

  • 確定申告書作成コーナーで拡張機能やJavaScriptで自動入力する手もあるだろうが、id要素の重複がフツーにあったので色々大変そう(そもそもあのページで拡張機能動くかは不明)
  • pdf-parse ^1.1.1 も使ってみたが、口座番号等の一部テキストが連結されて取得されてしまったので却下
  • PDF-Scrape ^0.9.5 も使ってみた。CLIでカジュアルにparse出来る点はいいのだが、こちらはPDF.jsとは違った場所でテキストが分割されていたり、氏名の間の半角スペースがtrimされていたため、他にも何かあるかもしれないと考えた結果、却下

参考

Discussion