watermark or header in excel file - python

I create a excel file from a dataframe:
#writer = pd.ExcelWriter('ΜΟΝΑΔΙΚΕΣ_ΠΡΟΣΛΗΨΕΙΣ.xlsx', engine='xlsxwriter')
#uniq_pros.to_excel(writer, sheet_name='Sheet1')
#writer.save()
how can add a watermark in every page of excel file?
or
a header with logo text and image in every first row of pages (or 25lines?)
with python

The usual way to add a watermark in Excel (as suggested by Microsoft) is to add an image to the header. Here is one way to do it via Pandas and XlsxWriter:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('test.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Set a worksheet header with image.
worksheet.set_header('&C&[Picture]',
{'image_center': 'watermark.png'})
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:
See also Example: Adding Headers and Footers to Worksheets in the XlsxWriter docs.

Related

Convert DataFrame to excel by preserving existing sheets and increase the column size of excel

I am trying to convert the DataFrame to excel without overwriting the existing sheet.
The solution is using pd.ExcelWriter with openpyxl engine which supports append mode.
Now, I have to increase the column size of the excel, I use pd.ExcelWriter with XlsxWriter engine but it overwrites the remaining sheets.
Openpyxl as an engine:
with pd.ExcelWriter("test.xlsx", engine="openpyxl", mode="a") as writer:
df.to_excel(writer, sheet_name="name", startrow=num, startcol=num)
XlsxWriter as an engine:
workbook = xlsxwriter.Workbook('test.xlsx')
worksheet = workbook.add_worksheet()
worksheet.set_column(0, 0, 20)
Can someone please suggest to me a solution where I can do both things:
Keep the existing sheets
Increase the column width
you can use your ExcelWriter to adjust the column width. Example below. Note that you can only add a new tab and the data with this, not update text within an existing tab. But, it will NOT delete any contents, like in case of xlsxwriter.
from openpyxl.utils.cell import get_column_letter
startRow = 12 #Change as per your req
startCol = 3 #Change as per your req
with pd.ExcelWriter("test.xlsx", engine="openpyxl", mode="a") as writer: #Your code
df.to_excel(writer, sheet_name="name", startrow=startRow, startcol=startCol) #Your code... mostly
worksheet = writer.sheets['name'] #Get worksheet name
for i, col in enumerate(df.columns): #For each column in df, set width to 60
worksheet.column_dimensions[get_column_letter(startCol+i+1)].width = 60

Use data from a different sheet for table using xlsxwriter

I am using xlsxwriter to generate a file with quite a few formulas. From there, I want to create a table on another sheet. Everything is pretty straightforward until I want to use data from a different sheet for the table.
The documentation only shows examples of already having the data you need, and then passing that to the .add_table as the 'data' parameter.
What I am trying to do is this: (Which is structured how the rest of xlsxwriter's formulas are.)
df = pd.DataFrame(stuff)
writer = pd.ExcelWriter('File.xlsx', engine = 'xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
workbook = writer.book
worksheet1 = writer.sheets['Sheet1']
worksheet2 = workbook.add_worksheet('Summary Page')
data = f"'Sheet1'!$A$1:$D${len(df)}"
worksheet2.add_table(f'A1:D{len(df)}', {'data':data})
workbook.close()
This approach adds the new sheet, and creates a table the correct size. But then fills in the "data" with 'data' as a string down the first column with one character in each cell.
Is there a way to create a table referencing data from another sheet using xlsxwriter?
ExcelWriter is (obviously) for writing Excelfiles.
If you want to read data from Excel after writing and saving it (did I get you right?!) use
ExcelFile.parse or read_excel to convert data to dataframe and write it again to Excel by ExcelWriter. Unfortunately xlsxwriter does not support appending, so you have to load and write all sheets again. Or just use the default openpyxl as engine. Could be omitted (as said: default) but to point out it is given in minimal working example:
import pandas as pd
df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
writer = pd.ExcelWriter('test.xlsx', engine='openpyxl')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
data = pd.read_excel('test.xlsx', usecols='A:B', sheet_name='Sheet1', index_col=0)
writer = pd.ExcelWriter('test.xlsx', engine='openpyxl', mode='a')
# shape our data here
data.to_excel(writer, sheet_name='Sheet2')
writer.save()

Python Xlsxwriter charting

I am trying to build a simple python script that reads data from a .csv file, formats the data to an easy to read layout, then either writes it to a new xlsx file or appends to an existing xlsx file, depending on user input. That all works well and I write to the new file using;
with pd.ExcelWriter(file_path) as writer:
df.to_excel(writer, sheet_name='Master')
Now I want to add a second sheet that contains excel charts from the data and have extended the above code to;
with pd.ExcelWriter(file_path) as writer:
df.to_excel(writer, sheet_name='Master')
book = writer.book
sheet = writer.sheets['Master']
chart_a = book.add_chart({'type': 'line'})
chart_a.add_series({
'categories': ['Master', 1, 0, trend_data_row, 0],
'values': ['Master', 1, 1, trend_data_row, 1],
})
chart_a.set_x_axis({'name': 'time', 'position_axis': 'on_tick'})
chart_a.set_y_axis({'name': 'value'})
chart_a.set_legend({'position': 'Bottom'})
sheet.insert_chart('A11', chart_a)
writer.save()
This adds the chart to the 'Master' sheet as expected, I don't understand how to create the second sheet and insert the chart there instead. I have tried changing sheet = writer.sheets to a new name [Graphs] but I guess its looking for an existing sheet with that name rather than creating one. Any help is really appreciatted.
I don't understand how to create the second sheet and insert the chart there instead.
You can do it like this:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_chart.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Master')
# Get the xlsxwriter workbook object.
workbook = writer.book
# Add a new worksheet.
worksheet = workbook.add_worksheet('Graphs')
# Create a chart object.
chart = workbook.add_chart({'type': 'column'})
# Configure the series of the chart from the dataframe data.
chart.add_series({'values': ['Master', 1, 1, 7, 1]})
# Insert the chart into the worksheet.
worksheet.insert_chart('D2', chart)
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:
then either writes it to a new xlsx file or appends to an existing xlsx file
XlsxWriter cannot write to an existing file.

pandas ExcelWriter write sheet direction right to left

I'm creating in python Django dynamic Excel file that is downloaded (not stored locally), and I need to make the sheet display from right to left and not from left to right.
Here is the code that I used:
import pandas
from io import BytesIO, StringIO
sio = BytesIO()
PandasDataFrame = pandas.DataFrame([['t1', 't2'], ['t3', 't4']], index = ['t1', 't2'], columns = ['t11', 't1'] )
PandasWriter = pandas.ExcelWriter(sio, engine='xlsxwriter')
PandasDataFrame.to_excel(PandasWriter, sheet_name='Sheet1')
PandasWriter.book.add_format({'reading_order': 2})
PandasWriter.save()
PandasWriter.close()
sio.seek(0)
workbook = sio.read()
response = HttpResponse(workbook,content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = 'attachment; filename=wrong_data.xlsx'
return (response)
Here is a simple Pandas example that demonstrates how to change the text, and also the worksheet direction. You can convert it to a Django example yourself.
# _*_ coding: utf-8
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': [u'نص عربي / English text'] * 6})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_simple.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Add the cell formats.
format_right_to_left = workbook.add_format({'reading_order': 2})
# Change the direction for the worksheet.
worksheet.right_to_left()
# Make the column wider for visibility and add the reading order format.
worksheet.set_column('B:B', 30, format_right_to_left)
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:
See the XlsxWriter docs on the worksheet right_to_left() method for more details.

Python: Writing Images and dataframes to the same excel file

I'm creating an excel dashboard and I want to generate an excel workbook that has some dataframes on half of the sheets, and .png files for the other half. I'm having difficulty writing them to the same file in one go. Here's what I currently have. It seems that when I run my for loop, it won't let me add additional worksheets. Any advice on how I might get my image files added to this workbook? I can't find anything about why I can't add any more worksheets Thanks!
dfs = dict()
dfs['AvgVisitsData'] = avgvisits
dfs['F2FCountsData'] = f2fcounts
writer = pd.ExcelWriter("MyData.xlsx", engine='xlsxwriter')
for name, df in dfs.items():
df.to_excel(writer, sheet_name=name, index = False)
Then I want to add a couple sheets with some images to the same excel workbook. Something like this, but where I'm not creating a whole new workbook.
workbook = xlsxwriter.Workbook('MyData.xlsx')
worksheet = workbook.add_worksheet('image1')
worksheet.insert_image('A1', 'MemberCollateral.png')
Anyone have any tips to work around this?
Here is an example of how to get a handle to the underlying XlsxWriter workbook and worksheet objects and insert an image:
import pandas as pd
# Create a Pandas dataframe from some data.
df = pd.DataFrame({'Data': [10, 20, 30, 20, 15, 30, 45]})
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('pandas_image.xlsx', engine='xlsxwriter')
# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')
# Get the xlsxwriter workbook and worksheet objects.
workbook = writer.book
worksheet = writer.sheets['Sheet1']
# Insert an image.
worksheet.insert_image('D3', 'logo.png')
# Close the Pandas Excel writer and output the Excel file.
writer.save()
Output:
See also Working with Python Pandas and XlsxWriter in the XlsxWriter docs for more examples
Here's the solution I came up with. I still cound't find a way to do this without re-importing the workbook with load_workbook but this got the job done.
# assign dataframes to dictionary and export them to excel
avgvisits = pd.DataFrame(pd.read_sql(avgvisits(), cnxn))
f2fcounts = pd.DataFrame(pd.read_sql(f2fcounts(), cnxn))
activityencounters = pd.DataFrame(pd.read_sql(ActivityEncounters(), cnxn))
activityencountersp = activityencounters.pivot_table(values='ActivityCount', index = ['Activity'], columns= ['QuarterYear'], aggfunc=np.max)
dfs = dict()
dfs['AvgVisitsData'] = avgvisits
dfs['F2FIndirect'] = f2fcounts
dfs['ActivityEncounters'] = activityencountersp
writer = pd.ExcelWriter("MyData.xlsx", engine='xlsxwriter')
for name, df in dfs.items():
if name != 'ActivityEncounters':
df.to_excel(writer, sheet_name=name, index=False)
else:
df.to_excel(writer, sheet_name=name, index=True)
writer.save()
writer.close()
# re-import the excel book and add the graph image files
wb = load_workbook('MyData.xlsx')
png_loc = 'MemberCollateral.png'
wb.create_sheet('MemberCollateralGraph')
ws = wb['MemberCollateralGraph']
my_png = openpyxl.drawing.image.Image(png_loc)
ws.add_image(my_png, 'A1')
png_loc = 'DirectIndirect.png'
ws = wb['F2FIndirect']
my_png = openpyxl.drawing.image.Image(png_loc)
ws.add_image(my_png, 'A10')
png_loc = 'QuarterlyActivitySummary.png'
ws = wb['ActivityEncounters']
my_png = openpyxl.drawing.image.Image(png_loc)
ws.add_image(my_png, 'A10')
wb.save('MyData.xlsx')

Categories