LoginSignup
2
3

More than 5 years have passed since last update.

Pythonでエクセルから条件付きCSV出力

Last updated at Posted at 2019-04-15

経緯

最近参画していた案件でタイトル通りの機能が必要であったため。
作成した内容を抜粋。

Github

機能

  • エンコード、改行コードを指定できる。
  • スキップする行を指定できる。
  • 文字列か数値か判断して、出力形式を分ける。
  • 小数(パーセント)は桁数指定
  • 結合セルもよしなに処理。

ライブラリについて

当初は、エクセル上00.0%書式のところ、ロジック上で書式を読み取り判断する仕様だった為、
書式データも読み取り可能なpandas、openpyxlを検討した。

採用

xlrd

  • 速かったから。2000行で4秒程度。20000行で40秒ぐらい
  • 結合セルも補間して処理してくれるから。
  • 書式読み取り不要になった為。

不採用

pandas 

  • エクセル良い取って、csv出力するだけにしたら、dataflameは機能過多で複雑に感じたから。

openpyxl

  • 重たかったから。2000行で15秒。xlrdの約三倍。 書式データを保持しているからか、初期読み込みに時間がかかる模様。
  • 結合セルをよしなに処理してくれなかったから。

ロジック詳細

import

import xlrd

エクセル読み取り

xls = xlrd.open_workbook(INPUT_XLSX)
sheet = xls.sheet_by_index(0)

rows = sheet.nrows # 行数 
cols = sheet.ncols # 列数

for r in range(0, rows):
    for c in range(0, cols):
        cell = sheet.cell(r,c)
cell.value # 値を取得
cell.ctype # 値のタイプを取得

CSV出力

エンコード、改行コード

file = open(OUTPUT_CSV, 'w', encoding = ENCODE, newline = NEWLINE)
ENCODE =>
'utf_8_sig' # UTF8 BOM付き
'utf_8' # UTF8
NEWLINE =>
'\r\n' # CRLF
'\n' # LF

出力用関数

# 文字列出力 (""で囲む)
def writeStr(value):
    return '\"' + str(value) + '\"'

# 数値出力
def writeNum(value):
    return str(value)

文字列か否か

# 文字列の場合
if(cell.ctype == xlrd.XL_CELL_TEXT):
    writeStr(cell.value)

数値か否か

if(cell.ctype == xlrd.XL_CELL_NUMBER):
    if(cell.value.is_integer()):
      writeNum(int(cell.value))
    # 少数の時 第3位まで
    else:
      writeNum(round(cell.value, ROUND))        
# 許有少数桁
ROUND = 3

整数か否か

value.is_integer()

 実施方法

python3 tocsv.py
2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3