文書中の特定のテーブルを読み取る方法について紹介します.
背景
Word ファイルにおいて,特定の章に記載されているテーブルの内容を読み取りたいシチュエーションは良くあるかと思います.
例えば次のような表が複数含まれる文書において,「そして」という章に含まれる表のみを読み取る場合です.
これを実現するのが次のスクリプトです.
スクリプト
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
#!/usr/bin/env ruby # -*- coding: utf-8 -*- Encoding.default_internal = "utf-8" Encoding.default_external = "utf-8" require 'win32ole' require 'pp' def get_pos_map(doc, style_name) pos_map = {} doc.Paragraphs.each do |para| next if (para.Range.Style.NameLocal != style_name) pos_map[para.Range.Text.gsub(%r|[\a\r\n\f]|, "")] = { start: para.Range.Start, end: para.Range.End, } end return pos_map end def get_table_list(doc, pos) table_list = [] doc.Tables.each do |table| next if table.Range.Start > pos[:end] next if table.Range.End < pos[:start] table_list.push(table) end return table_list end begin word = WIN32OLE.new("Word.Application") word.DisplayAlerts = false fso = WIN32OLE.new('Scripting.FileSystemObject') doc = word.Documents.Open({ FileName: fso.GetAbsolutePathName('./sample.docx'), ReadOnly: true }) pos_map = get_pos_map(doc, "見出し 1") table_list = get_table_list(doc, pos_map["そして"]) table_info_list = [] table_list.each do |table| table_info = [] (1..table.Rows.Count).each do |row| row_info = [] (1..table.Columns.Count).each do |col| row_info.push(table.Cell(row,col).Range.Text.gsub(%r|[\a\r\n\f]|, "")) end table_info.push(row_info) end table_info_list.push(table_info) end PP.pp(table_info_list, STDOUT, 30) ensure word.Quit end |
冒頭に掲載した内容の sample.docx ファイルに対して上記のスクリプトを実行すると,以下の出力が得られます.
1 2 3 |
[[["な", "に", "ぬ"], ["は", "ひ", "ふ"], ["ま", "み", "む"]]] |
解説
処理のポイントは,まず get_pos_map で章の範囲を取得する点です.その後,文書に含まれるテーブルの一覧の中から先ほどの範囲に含まれるものを抽出します.
コメント