'Copy pandas dataframe to excel using openpyxl
I have some complicated formating saved in a template file into which I need to save data from a pandas dataframe. Problem is when I use pd.to_excel to save to this worksheet, pandas overwrites the formatting. Is there a way to somehow 'paste values' form the df into the worksheet? I am using pandas 0.17
import openpyxl
import pandas as pd
wb= openpyxl.load_workbook('H:/template.xlsx')
sheet = wb.get_sheet_by_name('spam')
sheet.title = 'df data'
wb.save('H:/df_out.xlsx')
xlr = pd.ExcelWriter('df_out.xlsx')
df.to_excel(xlr, 'df data')
xlr.save()
Solution 1:[1]
openpyxl 2.4 comes with a utility for converting Pandas Dataframes into something that openpyxl can work with directly. Code would look a bit like this:
from openpyxl.utils.dataframe import dataframe_to_rows
rows = dataframe_to_rows(df)
for r_idx, row in enumerate(rows, 1):
for c_idx, value in enumerate(row, 1):
ws.cell(row=r_idx, column=c_idx, value=value)
You can adjust the start of the enumeration to place the cells where you need them.
See openpyxl documentation for more information.
Solution 2:[2]
I slightly modified @CharlieClark's great answer to avoid the index (which is not there in the original Excel file). Here is a ready-to-run code:
import pandas as pd
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl import load_workbook
wb = load_workbook('test.xlsx') # load as openpyxl workbook; useful to keep the original layout
# which is discarded in the following dataframe
df = pd.read_excel('test.xlsx') # load as dataframe (modifications will be easier with pandas API!)
ws = wb.active
df.iloc[1, 1] = 'hello world' # modify a few things
rows = dataframe_to_rows(df, index=False)
for r_idx, row in enumerate(rows, 1):
for c_idx, value in enumerate(row, 1):
ws.cell(row=r_idx, column=c_idx, value=value)
wb.save('test2.xlsx')
Solution 3:[3]
Here is the solution for you using clipboard:
import openpyxl
import pandas as pd
import clipboard as clp
#Copy dataframe to clipboard
df.to_clipboard()
#paste the clipboard to a valirable
cells = clp.paste()
#split text in varialble as rows and columns
cells = [x.split() for x in cells.split('\n')]
#Open the work book
wb= openpyxl.load_workbook('H:/template.xlsx')
#Get the Sheet
sheet = wb.get_sheet_by_name('spam')
sheet.title = 'df data'
#Paste clipboard values to the sheet
for i, r in zip(range(1,len(cells)), cells):
for j, c in zip(range(1,len(r)), r):
sheet.cell(row = i, column = j).value = c
#Save the workbook
wb.save('H:/df_out.xlsx')
Solution 4:[4]
you shoud to get your data shap first to determine the range of loop
wb_formats=load_workbook("template.xlsx")
ws_index=wb_formats.get_sheet_by_name("index")
daily_input= pd.read_excel(self.readfile,"input")
list_item=data_analysis1.groupby(["item_id"])["product_name"].unique()
list_item_size=pd.DataFrame(list_item,columns=["product_name"]).shape[0]
#create the index sheet:
r = 2 # start at 4th row
c = 1 # column 'a'
for row in range(0,list_item_size):
rows = list_item.iloc[row]
for item in rows:
ws_index.cell(row=r, column=c).value = item
c += 1 # Column 'd'
c = 1
r += 1
wb_formats.save(save_name)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Charlie Clark |
| Solution 2 | Basj |
| Solution 3 | Abbas |
| Solution 4 | Youssri Abo Elseod |
