Pull to refresh

Обработка Excel файлов с использованием Python

Reading time 4 min
Views 205K
image
По работе пришлось столкнуться с задачей обработки xls файлов средствами python. Немного по гуглив, я натолкнулся на несколько библиотек, с помощью которых можно работать с файлами excel.

Библиотеки:
— xlrd – дает возможность читать файлы Excel
— xlwt – создание и заполнение файлов Excel
— xlutils – набор утилит для расширения возможности предыдущих двух библиотек
— pyExcelerator – также дает возможность работать с файлами Excel, но давно не обновлялась.

Для своей задачи я использовал первые три библиотеки.
Задача была разбита на несколько частей: чтение файла с расширением xls; создание нового и заполнение его; создание копии файла на основе входного файла; удаление необходимых строк в выходном файле.

Чтение входного файла


Эта задача не отличается высокой сложностью. Документация и примеры, идущие в комплекте с xlrd, помогли быстро решить ее.
Пример кода:
import xlrd
rb = xlrd.open_workbook('d:/final.xls',formatting_info=True)
sheet = rb.sheet_by_index(0)
for rownum in range(sheet.nrows):
row = sheet.row_values(rownum)
for c_el in row:
print c_el


Создание нового файла и заполнение его


Эта задача оказалась не сложнее предыдущей. Документация и примеры помогли.
Пример кода:
import xlwt
from datetime import datetime

font0 = xlwt.Font()
font0.name = 'Times New Roman'
font0.colour_index = 2
font0.bold = True

style0 = xlwt.XFStyle()
style0.font = font0

style1 = xlwt.XFStyle()
style1.num_format_str = 'D-MMM-YY'

wb = xlwt.Workbook()
ws = wb.add_sheet('A Test Sheet')

ws.write(00'Test', style0)
ws.write(10, datetime.now(), style1)
ws.write(201)
ws.write(211)
ws.write(22, xlwt.Formula("A3+B3"))

wb.save('example.xls')


Создание копии файла на основе входного файла


Эта задача может решаться двумя путями. Вариант первый: открываем на чтение входной файл, создаем новый файл и по циклу переписываем все данные с одного файла в другой. Такое решение не сложно реализовать, поэтому пример кода выкладывать нет смысла. Вариант второй: воспользоваться библиотекой xlutils. В данной библиотеке есть много чего интересного и полезного, но для нашей задачи будет интересен именно xlutils.copy.
И так, пример кода по созданию файла на основании входного с использованием xlutils.copy:
import xlrd
import xlwt
from xlutils.copy import copy

rb = open_workbook('final.xls',on_demand=True,formatting_info=True)
wb = copy(rb)
wb.save("final_complete.xls")


Вот такой вот небольшой код получился. Для того чтобы он работал, обязательно должен стоять флаг on_demand=True. Благодаря использованию флага formatting_info выходной файл получается с такими же стилями оформления, как и входной. Для моей задачи это оказалась нужная опция.

Удаление строк по заданному условию


Для решения данной задачи было решено использовать фильтр. Один из вариантов — это переписывание из одного файла в другой, исключая те варианты, которые не выполняют заданное условие. Но тут есть одна загвоздка, если необходимо сохранить стиль оформление документа, то этот подход не подойдет (Если конечно вы заранее не знаете стиль оформления и можете задать его программно). Решение поставленной задачи было достигнуто посредством использования xlutils.filter. Задача: оставить в выходном Excel файле только те записи, которые содержатся в передаваемом списке.
Код, который решает данную задачу:
from xlutils.filter import GlobReader,BaseFilter,DirectoryWriter,process

myfile='final2.xls'
mydir='d:/' 

class MyFilter(BaseFilter): 

    goodlist = None
    
    def __init__(self,elist): 
        self.goodlist = goodlist
        self.wtw = 0
        self.wtc = 0
         

    def workbook(self, rdbook, wtbook_name): 
        self.next.workbook(rdbook, 'filtered_'+wtbook_name) 

    def row(self, rdrowx, wtrowx):
        pass

    def cell(self, rdrowx, rdcolx, wtrowx, wtcolx): 
        value = self.rdsheet.cell(rdrowx,rdcolx).value
        if value in self.goodlist:
            self.wtc=self.wtc+1 
            self.next.row(rdrowx,wtrowx)
        else:
            return
        self.next.cell(rdrowx,rdcolx,self.wtc,wtcolx)
        
        
data = """somedata1
somedata2
somedata3
somedata4
somedata5
"""


goodlist = data.split("\n")

process(GlobReader(os.path.join(mydir,myfile)),MyFilter(goodlist),DirectoryWriter(mydir))


Заключение


Используя набор из трех библиотек, поставленные задачи были решены. Было замечено следующее: при наличии во входном Excel файле графических элементов (картинки и т.д) в выходной файл они не переносятся. Возможно изучив эти библиотеки можно будет решить и эту часть задачи.

Ссылки


sourceforge.net/projects/pyexcelerator
www.python-excel.org — на три первых библиотеки.
groups.google.com/group/python-excel — группа, в которой обсуждают использование библиотек xlrd, xlwt и xlutils.

P.S. Думаю было бы неплохо перенести данный пост в тематический блог.
Tags:
Hubs:
+45
Comments 57
Comments Comments 57

Articles