Insert data in different sheets in Excel - python

I would like to fill different data in different sheets in excel. So far i am writing everything in 1 sheet.
I want to have for each i in for loop a different sheet( sheet1,sheet2...)
for i in range(1,11):
for k, v in drd_dictionary.items() :
if str(i) + "_" in k :
an.append(k)
reqs.append(v)
sheet_number=i
write_to_excel(an,reqs,str(sheet_number))
def write_to_excel(an,req_text,sheet_number):
workbook = xlsxwriter.Workbook('path.xlsx')
worksheet = workbook.add_worksheet()
worksheet.write_column('A1', an)
worksheet.write_column('B1', req_text)
workbook.close()

Looks like you're overwriting the workbook with each iteration. Pass the workbook as a parameter to the function. Initialize the workbook before the loop.
def write_to_excel(workbook, an,req_text,sheet_number):
worksheet = workbook.add_worksheet(sheet_number)
worksheet.write_column('A1', an)
worksheet.write_column('B1', req_text)
Here is the full working code:
import xlsxwriter
def write_to_excel(workbook, an,req_text,sheet_number):
worksheet = workbook.add_worksheet(sheet_number)
for i in range(len(an)):
worksheet.write(0,i, an[i])
for j in range(len(req_text)):
worksheet.write(0,j, req_text[j])
drd_dictionary = {"1_": "a", "2_": "2"}
an,reqs = [],[]
workbook = xlsxwriter.Workbook("data.xlsx")
for i in range(1,11):
for k, v in drd_dictionary.items() :
if str(i) + "_" in k :
an.append(k)
reqs.append(v)
sheet_number=i
write_to_excel(workbook, an,reqs,str(sheet_number))
workbook.close()

Related

Copying Specific Column from One Workbook to Another using Openpyxl

I am fairly new to python and trying to copy the data in workbook one, columns A,D,G, paste them into columns A,B,C, on the new workbook. I know how to copy one column or the whole worksheet but can't figure that out.
from openpyxl import load_workbook
wb1 = load_workbook('test1.xlsx')
wb2 = load_workbook('test2.xlsx')
ws1 = wb1.get_sheet_by_name('Sheet1')
ws2 = wb2.get_sheet_by_name('Sheet1')
mr = ws1.max_row
mc = ws1.max_column
for i in range (1, mr + 1):
for j in range (1, mc + 1):
c = ws1.cell(row=i, column=j)
ws2.cell(row=i, column=j).value = c.value
wb2.save('test2.xlsx')
That is the code I am using to copy the whole worksheet
I think you're looking for something like this
for i in range(1, mr + 1):
ws2['A' + str(i)].value = ws1['A' + str(i)].value
ws2['B' + str(i)].value = ws1['D' + str(i)].value
ws2['C' + str(i)].value = ws1['G' + str(i)].value

How do I write Excel sheet without protected it?

I got an Excel sheet, which included some protected cells.
I used python program to write some other cells, then the cells were all protected.
I dont want to protect the cells I write. How should I do?
Thanks.
wb = openpyxl.load_workbook('SecGen.xlsx')
ws = wb['5.1 Frame.Info']
cell = ws['K1']
cell.value = 'Oi, cm'
cell = ws['L1']
cell.value = 'Oj, cm'
for i in range(0, len(ori_e2k.line_se_point_list), 1):
for j in range(0, len(ori_e2k.line_se_point_list[i]), 1):
cell = ws.cell(row=i+2, column=j+2)
cell.value = ori_e2k.line_se_point_list[i][j]
wb.close()
openpyxl default enables protection.
Just disable it.
import openpyxl
from openpyxl.styles import Protection, Font
...
...
wb = openpyxl.load_workbook('SecGen.xlsx')
ws = wb['5.1 Frame.Info']
font = Font(name='Calibri')
cell = ws['K1']
cell.value = 'Oi, cm'
cell.protection = Protection(locked=False)
cell.font = Font(name='Calibri')
cell = ws['L1']
cell.value = 'Oj, cm'
cell.protection = Protection(locked=False)
cell.font = Font(name='Calibri')
for i in range(0, len(ori_e2k.line_se_point_list), 1):
for j in range(0, len(ori_e2k.line_se_point_list[i]), 1):
cell = ws.cell(row=i+2, column=j+2)
cell.value = ori_e2k.line_se_point_list[i][j]
cell.protection = Protection(locked=False)
cell.font = Font(name='Calibri')
wb.save('SecGen.xlsx')
wb.close()

writing Excel file while using for loop

I am trying to write data to an Excel file, during a for loop.
But what I am getting is a single line containing the last data received by the loop.
I have tried a couple of different methods but came short..
2 tries are list below
Any Ideas ?
def write_excel(x):
workbook = xlsxwriter.Workbook('ID_Num.xlsx')
worksheet = workbook.add_worksheet()
df = pd.DataFrame(
{'ID':[x],
'mail_one':[Email],
'second_mail':[second_mail],
'Num':[Num],
'date':[Date]})
row_num = 0
for key, value in df.items():
worksheet.write(0, row_num, key)
worksheet.write_row(1, row_num, value)
row_num += 1
workbook.close()
#df = pd.DataFrame(
# {'ID':[x],
# 'mail_one':[Email],
# 'second_mail':[second_mail],
# 'Num':[Num],
# 'date':[Date]})
# writer = ExcelWriter('ID_Num.xlsx')
# df.to_excel(writer,'ID_Num',index=False)
# writer.save()
if __name__ == "__main__":
for x in List:
my_dic = {}
my_dict["ID"] = x
my_dict["mail_one"] = Email
my_dict["second_mail"] = second_mail
my_dict["Num"] = str(Num)
my_dict["date"] = Date
print(my_dict)
write_excel(x)
I don't have xlsxwriter so I cannot test. The documentation says that it cannot modify an existing file so I suspect that every iteration of for x in List: you are over-writing your file (workbook = xlsxwriter.Workbook('ID_Num.xlsx')).
You can make multiple files with these changes:
def write_excel(x,i):
workbook = xlsxwriter.Workbook(f'ID_Num{i}.xlsx')
...
# and
for i,x in enumerate(List):
...
write_excel(x,i)
Or you could accumulate multiple dictionaries and pass all of them to your function
data = []
for x in List:
my_dic = {}
...
data.append(my_dic)
write_excel(data)
Changing the function to iterate over those dicts; making a new sheet for each one
def write_excel(data):
workbook = xlsxwriter.Workbook('ID_Num.xlsx')
for sht in data:
worksheet = workbook.add_worksheet()
df = pd.DataFrame(...
row_num = 0
for key, value in df.items():
worksheet.write(...
worksheet.write_row(...
row_num += 1
workbook.close()

TypeError: 'Sheet' object is not callable when combining data across excel

I am now working on combining data for 2 excel file. my approach is to use xlwt to create a new excel and corresponding sheet. and then use for loop to write into the newly created excel file. my code is as below,
#......
wbk = xlwt.Workbook()
sheet_0 = wbk.add_sheet('A')
sheet_1 = wbk.add_sheet('B')
wbk.save(os.path.join(currentPath, gsheet.cell(gsr, 2).value) + FullName + " " + time_now + ".xls")
wkbk = xlrd.open_workbook(
os.path.join(currentPath, gsheet.cell(gsr, 2).value) + FullName + " " + time_now + ".xls")
wb_merge = copy(wkbk)
wsheet_0 = wb_merge.get_sheet(0)
wsheet_1 = wb_merge.get_sheet(1)
workbook_merge_0 = xlrd.open_workbook(os.path.join(currentPath, filename0), formatting_info=True)
sheet_merge_0 = workbook_merge_0.sheet_by_index(0)
for r in range(0, total_row_0):
for c in range(0, total_col_0):
wsheet_1.write(r, c, sheet_merge_0(r, c).value)
#......
when i am running the whole code, error show TypeError: 'Sheet' object is not callable, pointing to the last row, i.e. wsheet_1.write(r, c, sheet_merge_0(r, c).value)
Any suggestion can be provided? Thanks in advance!

copy cell style openpyxl

I am trying to copy a sheet, default_sheet, into a new sheet new_sheet in the same workbook.
I did managed to create a new sheet and to copy the values from default sheet. How can I also copy the style of each cell into the new_sheet cells?
new_sheet = workbook.create_sheet()
new_sheet.title = sheetName
default_sheet = workbook.get_sheet_by_name('default')
new_sheet = workbook.get_sheet_by_name(sheetName)
for row in default_sheet.rows:
col_idx = float(default_sheet.get_highest_column())
starting_col = chr(65 + int(col_idx))
for row in default_sheet.rows:
for cell in row:
new_sheet[cell.get_coordinate()] = cell.value
<copy also style of each cell>
I am at the moment using openpyxl 1.8.2, but i have in mind to switch to 1.8.5.
One solution is with copy:
from copy import copy, deepcopy
new_sheet._styles[cell.get_coordinate()] = copy(
default_sheet._styles[cell.get_coordinate()])
As of openpyxl 2.5.4, python 3.4: (subtle changes over the older version below)
new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']
from copy import copy
for row in default_sheet.rows:
for cell in row:
new_cell = new_sheet.cell(row=cell.row, column=cell.col_idx,
value= cell.value)
if cell.has_style:
new_cell.font = copy(cell.font)
new_cell.border = copy(cell.border)
new_cell.fill = copy(cell.fill)
new_cell.number_format = copy(cell.number_format)
new_cell.protection = copy(cell.protection)
new_cell.alignment = copy(cell.alignment)
For openpyxl 2.1
new_sheet = workbook.create_sheet(sheetName)
default_sheet = workbook['default']
for row in default_sheet.rows:
for cell in row:
new_cell = new_sheet.cell(row=cell.row_idx,
col=cell.col_idx, value= cell.value)
if cell.has_style:
new_cell.font = cell.font
new_cell.border = cell.border
new_cell.fill = cell.fill
new_cell.number_format = cell.number_format
new_cell.protection = cell.protection
new_cell.alignment = cell.alignment
The StyleableObject implementation stores styles in a single list, _style, and style properties on a cell are actually getters and setters to this array. You can implement the copy for each style individually but this will be slow, especially if you're doing it in a busy inner loop like I was.
If you're willing to dig into private class attributes there is a much faster way to clone styles:
if cell.has_style:
new_cell._style = copy(cell._style)
FWIW this is how the optimized WorksheetCopy class does it in the _copy_cells method.
May be this is the convenient way for most.
from openpyxl import load_workbook
from openpyxl import Workbook
read_from = load_workbook('path/to/file.xlsx')
read_sheet = read_from.active
write_to = Workbook()
write_sheet = write_to.active
write_sheet['A1'] = read_sheet['A1'].value
write_sheet['A1'].style = read_sheet['A1'].style
write_to.save('save/to/file.xlsx')
I organized the answers above and the code below works for me.
(it copies the cell value and the cell format)
from openpyxl import load_workbook
from copy import copy
wb = load_workbook(filename = 'unmerge_test.xlsx') #your file name
ws = wb['sheet_merged'] #your sheet name in the file above
for group in list(ws.merged_cells.ranges):
min_col, min_row, max_col, max_row = group.bounds
cell_start = ws.cell(row = min_row, column = min_col)
top_left_cell_value = cell_start.value
ws.unmerge_cells(str(group))
for i_row in range(min_row, max_row + 1):
for j_col in range(min_col, max_col + 1):
ws.cell(row = i_row, column = j_col, value = top_left_cell_value)
#copy the cell format
ws.cell(row = i_row, column = j_col).alignment = copy(cell_start.alignment)
ws.cell(row = i_row, column = j_col).border = copy(cell_start.border)
ws.cell(row = i_row, column = j_col).font = copy(cell_start.font)
wb.save("openpyxl_unmerged.xlsx")
Hope this helps!

Categories