用python + openpyxl管理excel二〇〇五文书档案思路以及心得,

if not cell.value
  continue

http://www.bkjia.com/Pythonjc/838348.htmlwww.bkjia.comtruehttp://www.bkjia.com/Pythonjc/838348.htmlTechArticle用python +
openpyxl管理excel二〇〇六文书档案思路以及心得, 搜索工具
明确职责之后第一步正是找个趁手的库来职业。 Python
Excel上列出了xlrd、xlwt、xl…

为了防止获取的数码两端有看不见的空格(excel文件里很广泛的坑),记得strip()

用python + openpyxl管理excel2006文书档案思路以及心得,

寻觅工具

规定职责之后第一步就是找个趁手的库来干活。 Python
Excel上列出了xlrd、xlwt、xlutils这一个包,不过

它们都相比较老,xlwt乃至不协助07版之后的excel
它们的文书档案不太协和,都恐怕需求去读源代码,而老姐的职分比较紧,加上笔者及时在早先时期,未有那个日子细读源代码
再一番搜索后自个儿找到了openpyxl,协理07+的excel,一贯有人在敬服,文书档案清晰易读,参照Tutorial和API文书档案非常快就能够上手,就是它了~

安装

本条很轻便,直接pip install openpyxl,呵呵呵~

因为自个儿无需管理图片,就不曾装pillow。

局地怀恋

源文件差不离二个在1~2MB左右,相当的小,所以能够直接读入内存处理。
既然是管理excel,並且他们全体组料定都以win下办事(数据都用excel存了=
=,商科的人啊……),那几个剧本照旧在win下做呢
这些职务完全没有须求笔者对现成的文本做修改!囧……笔者只要读入、管理、再写出另多个文书就行了

上学使用

哦,正是开荒cmd,然后用python的shell各样玩这些模块来上手……(win下未有装ipython,囧)

做那些小本子基本上作者只要求import多个东西

from openpyxl import Workbook
from openpyxl import load_workbook

load_workbook从名称想到所包含的意义是把公文导入到内部存款和储蓄器,Workbook是最基本的贰个类,用来在内部存款和储蓄器里成立文件最终写进磁盘的。

干活

率先作者要求导入那一个文件

inwb = load_workbook(filename)

收获的就是贰个workbook对象

接下来本人急需创建一个新的文本

outwb = Workbook()

紧接着在这几个新文件里,用create_sheet新建多少个工作表,比方

careerSheet = outwb.create_sheet(0, 'career')

就能够从头顶插入一个叫career的工作表(也正是说用法类似python
list的insert)

接下去本人须要遍历输入文件的每一个职业表,并且依据表名做一些办事(e.g.如果表名不是数字,我不要求处理),openpyxl扶助用字典同样的法子通过表名获取专门的学业表,获取多少个专门的学问簿的表名的办法是get_sheet_names

for sheetName in inwb.get_sheet_names():
  if not sheetName.isdigit():
    continue
  sheet = inwb[sheetName]

获得专门的职业表之后,正是按列和行管理了。openpyxl会依靠职业表里实际有数据的区域来规定行数和列数,获取行和列的情势是sheet.rows和sheet.columns,它们都得以像list同样用。比方,假使自个儿想跳过多少少于2列的表,可以写

if len(sheet.columns) < 2:
  continue

假使自己想获得那些工作表的前两列,能够写

colA, colB = sheet.columns[:2]

除开用columns和rows来获得那么些专业表的种类之外,仍可以够用excel的单元格编码来获取二个区域,例如

cells = sheet['A1':'B20']

有一点像excel自个儿的函数,能够拉出一块二维的区域~

为了有助于管理,蒙受一个一直不C列的专门的职业表,作者要开创二个和A列等长的空的C列出来,那么我得以用sheet.cell那个措施,通过传播单元格编号和增添空值来成立新列。

alen = len(colA)
for i in range(1, alen + 1):
  sheet.cell('C%s' % (i)).value = None

留神:excel的单元格命名是从1起来的~

上边的代码也体现出来了,获取单元格的值是用cell.value(能够是左值也足以是右值),它的类型能够是字符串、浮点数、整数、或然时间(datetime.datetime),excel文件里也会变卦对应档案的次序的数据。

收获各种单元格的值之后,就能够展开操作了~openpyxl会自
动将字符串用unicode编码,所以字符串都以unicode类型的。

除去逐个各个单元格用cell.value修改值以外,还能一行行append到办事表里

sheet.append(strA, dateB, numC)

 最终,等新的文件写好,直接用workbook.save保存就行

outwb.save("test.xlsx")

本条会覆盖当前已有个别文件,乃至你在此之前读取到内部存款和储蓄器的要命文件。

一对要注意的地点
假使要在遍历一列的各种单元格的时候得到当前单元格的在那个column对象里的下标

for idx, cell in enumerate(colA):
  # do something...

为了幸免获取的数据两端有看不见的空格(excel文件里很遍布的坑),记得strip()

万一职业表里的单元格未有数据,openpyxl会让它的值为None,所以假如要依靠单元格的值做管理,无法事先假定它的项目,最棒用

if not cell.value
  continue

等等的语句来先行判别

设若要拍卖的excel文件里有为数非常多noise,举例当您预期一个单元格是时刻的时候,某个表的数目只怕是字符串,这时候能够用

if isinstance(cell.value, unicode):
  break

等等的话语管理。

win下的cmd仿佛不太好设定用utf-8的code
page,借使是简体汉语的话能够用936(GBK),print的时候会自动从unicode转形成GBK输出到终极。
 

一对帮衬管理中文题目标小函数
本人管理的表有一点点大于GBK范围的字符,当小编需求把部分新闻print出来监控管理速度的时候特别费劲,幸好它们都是足以无视的,作者间接用空格替换再print也行,所以加上一些自家自然就要替换掉的分隔符,作者能够:

# annoying seperators
dot = u'\u00b7'
dash = u'\u2014'
emph = u'\u2022'
dot2 = u'\u2027'

seps = (u'.', dot, dash, emph, dot2)

def get_clean_ch_string(chstring):
  """Remove annoying seperators from the Chinese string.

  Usage:
    cleanstring = get_clean_ch_string(chstring)
  """
  cleanstring = chstring
  for sep in seps:
    cleanstring = cleanstring.replace(sep, u' ')
  return cleanstring

除此以外小编还只怕有一个急需,是把斯洛伐克共和国(The Slovak Republic)语名[空格]中文名分成日语姓、西班牙语名、中文姓、汉语名。

第一本身索要能把乌克兰(Ukraine)语和华语分割开,小编的办法是用正则相配,依照布满中法文字符在unicode的范围来套。相称土耳其(Turkey)语和汉语的正则pattern如下:

# regex pattern matching all ascii characters
asciiPattern = ur'[%s]+' % ''.join(chr(i) for i in range(32, 127))
# regex pattern matching all common Chinese characters and seporators
chinesePattern = ur'[\u4e00-\u9fff. %s]+' % (''.join(seps))

斯拉维尼亚语就用ASCII可打字与印刷字符的限定替代,常见普通话字符的范围是\u4e00-\u9fff,那多少个seps是前面提到过的压倒GBK范围的局部字符。
除了简便的划分,作者还亟需管理独有普通话名尚未乌Crane语名、唯有拉脱维亚语名未有汉语名等情景,推断逻辑如下:

def split_name(name):
  """Split [English name, Chinese name].

    If one of them is missing, None will be returned instead.
  Usage:
    engName, chName = split_name(name)
  """
  matches = re.match('(%s) (%s)' % (asciiPattern, chinesePattern), name)
  if matches: # English name + Chinese name
    return matches.group(1).strip(), matches.group(2).strip()
  else:
    matches = re.findall('(%s)' % (chinesePattern), name)
    matches = ''.join(matches).strip()
    if matches: # Chinese name only
      return None, matches
    else: # English name only
      matches = re.findall('(%s)' % (asciiPattern), name)
      return ''.join(matches).strip(), None

赢得了中文名之后,作者索要分割成姓和名,因为任务须求无需把姓名分割得很明朗,小编就遵照分布的国语名姓名分割格局来分——四个字or八个字的率先个字是姓,多个字的前多个字是姓,名字带分隔符的(少数民族名字)分隔符前是姓(这里运用了前方的get_clean_ch_string函数来移除分隔符),名字再长一些又不带分割符的,即便任何字符串都以名字。(注意法语的first
name 指的是名,last name指的是姓,2333)

def split_ch_name(chName):
  """Split the Chinese name into first name and last name.

    * If the name is XY or XYZ, X will be returned as the last name.
    * If the name is WXYZ, WX will be returned as the last name.
    * If the name is ...WXYZ, the whole name will be returned
     as the last name.
    * If the name is ..ABC * XYZ..., the part before the seperator
     will be returned as the last name.
  Usage:
    chFirstName, chLastName = split_ch_name(chName)
  """
  if len(chName) < 4: # XY or XYZ
    chLastName = chName[0]
    chFirstName = chName[1:]
  elif len(chName) == 4: # WXYZ
    chLastName = chName[:2]
    chFirstName = chName[2:]
  else: # longer
    cleanName = get_clean_ch_string(chName)
    nameParts = cleanName.split()
    print u' '.join(nameParts)
    if len(nameParts) < 2: # ...WXYZ
      return None, nameParts[0]
    chLastName, chFirstName = nameParts[:2] # ..ABC * XYZ...
  return chFirstName, chLastName

分开葡萄牙语名就非常的粗略了,空格分开,第一片段是名,第二片段是姓,其他情况有的时候不管就行。

取得的就是一个workbook对象

def split_ch_name(chName):
  """Split the Chinese name into first name and last name.

    * If the name is XY or XYZ, X will be returned as the last name.
    * If the name is WXYZ, WX will be returned as the last name.
    * If the name is ...WXYZ, the whole name will be returned
     as the last name.
    * If the name is ..ABC * XYZ..., the part before the seperator
     will be returned as the last name.
  Usage:
    chFirstName, chLastName = split_ch_name(chName)
  """
  if len(chName) < 4: # XY or XYZ
    chLastName = chName[0]
    chFirstName = chName[1:]
  elif len(chName) == 4: # WXYZ
    chLastName = chName[:2]
    chFirstName = chName[2:]
  else: # longer
    cleanName = get_clean_ch_string(chName)
    nameParts = cleanName.split()
    print u' '.join(nameParts)
    if len(nameParts) < 2: # ...WXYZ
      return None, nameParts[0]
    chLastName, chFirstName = nameParts[:2] # ..ABC * XYZ...
  return chFirstName, chLastName
if len(sheet.columns) < 2:
  continue

源文件差不离二个在1~2MB左右,比很小,所以可以间接读入内部存款和储蓄器管理。
既然是管理excel,并且他们任何组显然都以win下工作(数据都用excel存了=
=,商科的人呀……),这几个剧本依然在win下做吗
本条职分完全无需自己对现成的文件做修改!囧……作者要是读入、管理、再写出另二个文件就行了

获取工作表之后,便是按列和行管理了。openpyxl会基于工作表里实际有数量的区域来规定行数和列数,获取行和列的法子是sheet.rows和sheet.columns,它们都足以像list一样用。比方,要是本人想跳过数码少于2列的表,可以写

# regex pattern matching all ascii characters
asciiPattern = ur'[%s]+' % ''.join(chr(i) for i in range(32, 127))
# regex pattern matching all common Chinese characters and seporators
chinesePattern = ur'[\u4e00-\u9fff. %s]+' % (''.join(seps))
if isinstance(cell.value, unicode):
  break

它们都相比较老,xlwt以至不支持07版之后的excel
它们的文书档案不太对劲儿,都恐怕必要去读源代码,而老姐的义务相比较紧,加上自身立马在末尾时期,未有那个时刻细读源代码
再一番搜求后自身找到了openpyxl,辅助07+的excel,平素有人在维护,文书档案清晰易读,参照Tutorial和API文档非常的慢就能够上手,正是它了~

接下去本人索要遍历输入文件的种种工作表,并且依据表名做一些行事(e.g.假如表名不是数字,作者无需管理),openpyxl帮助用字典同样的章程通过表名获取工作表,获取二个工作簿的表名的措施是get_sheet_names

安装

假设职业表里的单元格比相当少,openpyxl会让它的值为None,所以只要要基于单元格的值做管理,不能够事先假定它的类型,最棒用

因为自个儿无需管理图片,就从未有过装pillow。

outwb.save("test.xlsx")
sheet.append(strA, dateB, numC)

等等的言辞管理。

为了便于管理,境遇一个从没有过C列的专业表,作者要创建一个和A列等长的空的C列出来,那么自个儿能够用sheet.cell那一个方法,通过传播单元格编号和丰裕空值来创设新列。

from openpyxl import Workbook
from openpyxl import load_workbook

win下的cmd仿佛不太好设定用utf-8的code
page,假使是简体中文的话能够用936(GBK),print的时候会活动从unicode转变来GBK输出到极限。

做那些小本子基本上作者只须求import八个东西

本条会覆盖当前已部分文件,以致你从前读取到内部存款和储蓄器的特别文件。

for sheetName in inwb.get_sheet_names():
  if not sheetName.isdigit():
    continue
  sheet = inwb[sheetName]

上边包车型大巴代码也显得出来了,获取单元格的值是用cell.value(能够是左值也得以是右值),它的品类能够是字符串、浮点数、整数、恐怕时间(datetime.datetime),excel文件里也会转变对应项指标多少。

搜索工具

获得每一个单元格的值之后,就足以拓展操作了~openpyxl会自
动将字符串用unicode编码,所以字符串都是unicode类型的。

careerSheet = outwb.create_sheet(0, 'career')

此外笔者还应该有贰个需要,是把土耳其语名[空格]汉语名分成塞尔维亚共和国语姓、斯洛伐克共和国(The Slovak Republic)语名、汉语姓、汉语名。

葡萄牙语就用ASCII可打印字符的限定替代,常见普通话字符的范围是\u4e00-\u9fff,那些seps是前边提到过的胜出GBK范围的有个别字符。
除了简约的划分,我还亟需管理独有中文名尚未意大利共和国语名、独有俄文名未有汉语名等景况,决断逻辑如下:

一对设想

学习运用

colA, colB = sheet.columns[:2]
def split_name(name):
  """Split [English name, Chinese name].

    If one of them is missing, None will be returned instead.
  Usage:
    engName, chName = split_name(name)
  """
  matches = re.match('(%s) (%s)' % (asciiPattern, chinesePattern), name)
  if matches: # English name + Chinese name
    return matches.group(1).strip(), matches.group(2).strip()
  else:
    matches = re.findall('(%s)' % (chinesePattern), name)
    matches = ''.join(matches).strip()
    if matches: # Chinese name only
      return None, matches
    else: # English name only
      matches = re.findall('(%s)' % (asciiPattern), name)
      return ''.join(matches).strip(), None

除开逐条每个单元格用cell.value修改值以外,还足以一行行append到办事表里

for idx, cell in enumerate(colA):
  # do something...

load_workbook看名称就可以想到其意义是把公文导入到内部存款和储蓄器,Workbook是最中央的贰个类,用来在内部存款和储蓄器里创制文件最终写进磁盘的。

# annoying seperators
dot = u'\u00b7'
dash = u'\u2014'
emph = u'\u2022'
dot2 = u'\u2027'

seps = (u'.', dot, dash, emph, dot2)

def get_clean_ch_string(chstring):
  """Remove annoying seperators from the Chinese string.

  Usage:
    cleanstring = get_clean_ch_string(chstring)
  """
  cleanstring = chstring
  for sep in seps:
    cleanstring = cleanstring.replace(sep, u' ')
  return cleanstring
cells = sheet['A1':'B20']

而外用columns和rows来收获那么些工作表的行列之外,还能用excel的单元格编码来获得一个区域,比方

率先小编索要导入那个文件

就能从头顶插入二个叫career的职业表(也正是说用法类似python
list的insert)

哦,就是展开cmd,然后用python的shell各样玩那几个模块来上手……(win下未有装ipython,囧)

这些很轻易,直接pip install openpyxl,呵呵呵~

alen = len(colA)
for i in range(1, alen + 1):
  sheet.cell('C%s' % (i)).value = None

细分法文名就很简短了,空格分开,第一有的是名,第一局部是姓,别的情状权且不管就行。

有一点像excel本人的函数,能够拉出一块二维的区域~

等等的语句来先行决断

一些扶持管理汉语标题标小函数
自己管理的表有点过量GBK范围的字符,当本身急需把部分新闻print出来监察和控制管理速度的时候特别艰苦,幸而它们都是能够漠视的,小编直接用空格替换再print也行,所以加上一些本人本来将要替换掉的分隔符,小编可以:

借使要管理的excel文件里有许多noise,举例当你预期四个单元格是光阴的时候,有个别表的数额恐怕是字符串,那时候能够用

接着在那些新文件里,用create_sheet新建多少个职业表,比如

首先自身索要能把塞尔维亚(Република Србија)语和国文分割开,我的艺术是用正则相称,依照布满中国和日本文字符在unicode的限制来套。相配斯洛伐克共和国(The Slovak Republic)语和华语的正则pattern如下:

一部分要专注的地点
万一要在遍历一列的每种单元格的时候得到当前单元格的在这一个column对象里的下标

干活

假若自个儿想获得这么些职业表的前两列,能够写

规定任务之后第一步就是找个趁手的库来办事。 Python
Excel上列出了xlrd、xlwt、xlutils那多少个包,不过

outwb = Workbook()
inwb = load_workbook(filename)

留心:excel的单元格命名是从1从头的~

接下来本身索要创建二个新的文件

赢得了中文名之后,作者索要分割成姓和名,因为职分供给不需求把姓名分割得很显明,作者就遵照遍布的汉语名姓名分割形式来分——三个字or三个字的率先个字是姓,八个字的前八个字是姓,名字带分隔符的(少数民族名字)分隔符前是姓(这里运用了前边的get_clean_ch_string函数来移除分隔符),名字再长一些又不带分割符的,假若任何字符串都以名字。(注意爱沙尼亚语的first
name 指的是名,last name指的是姓,2333)

最终,等新的文本写好,间接用workbook.save保存就行

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图