I am using openpyxl 2.2.6 from the bitbucket repository. I tried the simple example from the documentation
This however produces a blank workbook with a single sheet approproately named "MyTestSheet" . but values in any cell.
What am I missing to get write to a cell to work.
from openpyxl import Workbook
wb = Workbook(optimized_write = True)
ws = wb.create_sheet(title="MyTestSheet")
from openpyxl.writer.dump_worksheet import WriteOnlyCell
from openpyxl.comments import Comment
from openpyxl.styles import Style, Font
cell = WriteOnlyCell(ws, value="hello world")
cell.font = Font(name='Courrier', size=36)
cell.comment = Comment(text="A comment", author="Author's Name")
wb.save("testwr_so.xlsx")
You need to append the cell to the worksheet:
ws.append([cell]) # you must always append a sequence
Related
I have a streamlit app that allow user to read excel file and try to split each sheet into a different workbook for this I am using the xlwings package when I try to debug the code it crash and display the error below:
error :com_error:(-2147221008,'Colnitialize has not been called.',None,None)
What does this error mean? And how to fix it?
Code:
import streamlit as st
import pandas as pd
import numpy as np
from pathlib import Path
import xlwings as xw
sheet5_path = "C:/Users/gm/Documents"
st.markdown("""
<style>
.header_title {
font-size:30px !important;
color:black;
text-align :center
}
.big-font {
font-size:50px !important;
color:Red
</style>
""", unsafe_allow_html=True)
st.title("Excel Split & Send")
try:
data = st.sidebar.file_uploader("Upload Dataset",type=["csv","xlsx","xls"])
except Exception as e:
st.write("error is: {}".format(e))
if data is not None:
sheet1,sheet2,sheet3,sheet4,sheet5 = None,None,None,None,None
with pd.ExcelFile(data,) as reader:
sheet1 = pd.read_excel(reader,sheet_name="sheet1")
sheet2 = pd.read_excel(reader,sheet_name="sheet2")
sheet3 = pd.read_excel(reader,sheet_name="sheet3")
sheet4 = pd.read_excel(reader,sheet_name="sheet4")
sheet5 = pd.read_excel(reader,sheet_name="sheet5")
st.write(sheet1.finished[0])
st.write(sheet1.unfinished[0])
st.markdown('<p class="header_title">sheet1|{}</p>'.format(str(sheet1.shape[0])), unsafe_allow_html=True)
sheet1 = pd.read_excel(reader,sheet_name="sheet1",usecols=[0,1,2,3,4])
st.dataframe(sheet1)
st.write(sheet2.finished[0])
st.write(sheet2.unfinished[0])
st.markdown('<p class="header_title">sheet2|{}</p>'.format(str(sheet2.shape[0])), unsafe_allow_html=True)
sheet2 = pd.read_excel(reader,sheet_name="sheet2",usecols=[0,1,2,3,4])
st.dataframe(sheet2)
st.write(sheet3.finished[0])
st.write(sheet3.unfinished[0])
st.markdown('<p class="header_title">sheet3|{}</p>'.format(str(sheet3.shape[0])), unsafe_allow_html=True)
sheet3 = pd.read_excel(reader,sheet_name="sheet3",usecols=[0,1,2,3,4])
st.dataframe(sheet3)
st.write(sheet4.finished[0])
st.write(sheet4.unfinished[0])
st.markdown('<p class="header_title">sheet4|{} </p>'.format(str(sheet4.shape[0])), unsafe_allow_html=True)
sheet4 = pd.read_excel(reader,sheet_name="sheet4",usecols=[0,1,2,3,4])
st.dataframe(sheet4)
st.write(sheet5.finished[0])
st.write(sheet5.unfinished[0])
st.markdown('<p class="header_title">sheet5|{} </p>'.format(str(sheet5.shape[0])), unsafe_allow_html=True)
sheet5 = pd.read_excel(reader,sheet_name="sheet5",usecols=[0,1,2,3,4])
st.dataframe(sheet5)
if st.sidebar.button("Split & Send"):
#create xlwings object
app = xw.App(visible = False)
# create workbook
wb = xw.Book(data)
# iterate over the sheets of the created workbook
# if sheet name = total delete it (do not copy it)
for sheet in wb.sheets:
if "total" in sheet.name:
sheet.delete()
# create new work book copy the first sheet
else:
wb_new = app.books.add()
sheet.copy(after = wb_new.sheets[0])
wb_new.sheets[0].delete()
#delete the columns G:H
wb_new.sheets[0].range('G:H').delete()
# save the new excel files as name of each sheet
if "sheet5" in sheet.name:
wb_new.save(f"{sheet5_path}/{sheet.name}.xlsx")
else:
wb_new.save(f"{sheet.name}.xlsx")
# close the create workbook
wb_new.close()
else:
st.markdown('<p class="big-font">You Need to Upload a FILE !!</p>', unsafe_allow_html=True)
Define xw.App() after defining the existing data.
if st.sidebar.button("Split & Send"):
wb = xw.Book(data)
# Use context manager to prevent zombie processes.
with xw.App(visible=False) as app:
wb_new = app.books.add()
# ...
wb_new.close()
wb.close()
I solved this question by importing pythoncom package and call the pythoncom.CoInitialize() each time the button is pressed
Background
I have a list of values in column A (which differ from worksheet to worksheet). I wanted to identify a subset of values to be matched and if a match was made between lists then the script will add the value from the tuple list to column P and moves downwards per value (see picture Script output).
Problem
The script kind of works, accept if the value in tuple is not found the Column A list, then it creates an empty cell in Excel and moves down to the next cell (see picture - Excel output).
Questions
What is the best way to avoid empty cells if the value from the tuple is not in the list?
Script
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.styles import Color, PatternFill, Font, Border
from openpyxl.styles import colors
from openpyxl.cell import Cell
import colorama
from colorama import init
init()
from colorama import Fore, Style, Back
import os
import shutil
import math
from decimal import Decimal
from openpyxl.styles import Alignment
from inspect import currentframe
import time
########################################
#########################################
src_path ="/Users/data/"
xlfileName = "test.xlsx"
xlfile = src_path + xlfileName
wb = Workbook()
wb = load_workbook(xlfile)
#########################################
#########################################
def get_linenumber():
cf = currentframe()
return cf.f_back.f_lineno
#########################################
#########################################
non_cash_tup = (
"Depreciation & amortisation", "Deferred income taxes", "Stock-based compensation", "Change in working capital",
"Accounts receivable", "Inventory", "Accounts payable", "Other non-cash items")
for xws in wb.sheetnames:
print(Style.RESET_ALL)
print(Fore.BLUE, "Looping Through Worksheet Name -- ", worksheet, "Script line is -- ", get_linenumber())
print(Style.RESET_ALL)
worksheet = wb[xws]
cell_list = []
for cell in worksheet['A']:
cell_list.append(cell.value)
for i, name in enumerate(non_cash_tup):
if name in cell_list:
print(Fore.LIGHTGREEN_EX, name, "is in the list")
column_cell = 16
worksheet.cell(column=column_cell, row=i+2, value=name)
else:
print(Fore.LIGHTRED_EX, name, "is not in the list")
wb.save(xlfile)
Use the set() function.
The set() function in Python uses to take an argument and convert it into a set object. It can take arguments like lists, tuples and dictionaries. The argument is called iterable. The output of elements might not be in the same order because items passed as list were not in order.
non_cash_tup = (
"Depreciation & amortisation", "Deferred income taxes", "Stock-based compensation", "Change in working capital",
"Accounts receivable", "Inventory", "Accounts payable", "Other non-cash items")
for xws in wb.sheetnames:
print(Style.RESET_ALL)
print(Fore.BLUE, "Looping Through Worksheet Name -- ", worksheet, "Script line is -- ", get_linenumber())
print(Style.RESET_ALL)
worksheet = wb[xws]
cell_list = []
for cell in worksheet['A']:
cell_list.append(cell.value)
matching = set(non_cash_tup) & set(cell_list)
#print(matching)
for i, name in enumerate(matching):
print(Fore.LIGHTGREEN_EX, name, "is in the list")
column_cell = 16
worksheet.cell(column=column_cell, row=i+2, value=name)
wb.save(xlfile)
i am trying to make an automated xlsx document creator, for this i want to make some of the cells to have bold font, this is part of the code i use
from openpyxl import load_workbook
from openpyxl.styles import Font
from openpyxl.styles.colors import Color
wb_orden = load_workbook(filename = 'resg.xlsx')
ws_orden = wb_orden["Resguardo"]
italic24Font = Font( size = 24, italic = True, bold = True)
ws_orden['A6'] = "hsadgfagahgafdhg"
ws_orden['A6'].font = italic24Font
NAME = "generated/"+"res_"+order+".xlsx"
wb_orden.save(filename = NAME)
but when i see the xlsx file the A6 cell is changed to hsadgfagahgafdhg, but it isn't bold. thanks for reading i hope you can help me whit this
i also tried this but still not working
ws_orden['A6'].font = Font(size=23, underline='single', color='FFBB00', bold=True, italic=True)
I'm using openpyxl to write data into excel files. I defined a function create_style to create named styles by passing a name and font, alignment, border styles etc. Once a style is created it'll be added to workbook and can be used anytime. In my case, NamedStyle is setting the alignment attributes to None. However, fonts,fills are working fine. I couldn't figure the problem.
Here's the code.
import os
from openpyxl import Workbook,load_workbook
from openpyxl.styles import Alignment, Font, NamedStyle
# to create a style passing workbook, name and optional arguments like font etc
def create_style(wb,stylename,**kwargs):
if stylename not in wb.named_styles:
style = NamedStyle(name=stylename)
for key,value in kwargs.items():
if value is not None:
setattr(style,key,value)
wb.add_named_style(style)
excelpath = '/path/to/my/master-excel-file.xlsx'
workbook = load_workbook(excelpath) if os.path.isfile(excelpath) else Workbook()
sheetname = 'sheet1'
sheets = workbook.get_sheet_names()
if sheetname in sheets:
print('loading existing sheet')
worksheet = workbook.get_sheet_by_name(sheetname)
else:
print('creating sheet...')
worksheet = workbook.create_sheet(sheetname)
font_1 = Font(name='Arial', size=18)
alignment_1 = Alignment(horizontal='general',
vertical='center')
create_style(workbook,'style1',font=font_1,alignment=alignment_1)
workbook.save(excelpath)
# My doubt is here
print(workbook._named_styles['style1'].font)
print('\n')
print(workbook._named_styles['style1'].alignment)
Let's assume there's no excel file in the path, then the code will create new excel file and create 'style1' and saves it in the workbook.
output1 :
creating sheet...
<openpyxl.styles.fonts.Font object>
Parameters:
name='Arial', charset=None, family=None, b=False, i=False, strike=None,
outline=None, shadow=None, condense=None, color=None, extend=None, sz=18.0,
u=None, vertAlign=None, scheme=None
<openpyxl.styles.alignment.Alignment object>
Parameters:
horizontal='general', vertical='center', textRotation=0, wrapText=None,
shrinkToFit=None, indent=0.0, relativeIndent=0.0, justifyLastLine=None,
readingOrder=0.0
When I run the same code again, None is assigned to all alignment parameters.
output 2:
loading existing sheet
<openpyxl.styles.fonts.Font object>
Parameters:
name='Arial', charset=None, family=None, b=False, i=False, strike=None,
outline=None, shadow=None, condense=None, color=None, extend=None, sz=18.0,
u=None, vertAlign=None, scheme=None
<openpyxl.styles.alignment.Alignment object>
Parameters:
horizontal=None, vertical=None, textRotation=0, wrapText=None,
shrinkToFit=None, indent=0.0, relativeIndent=0.0, justifyLastLine=None,
readingOrder=0.0
which means the style1 losing data regarding alignment on every run while font is working just fine. In other words, style1 isn't retaining the alignment. Why is it happening ?
I'm using openpyxl 2.0.5 and python 3.4 and I'm simply trying to set the font color to a cell to red
from openpyxl import Workbook
from openpyxl.styles import Color, Font, Style, colors
wb = Workbook()
ws = wb.active
cell = 'A1'
ws[cell].styles = Style(font=Font(color=Color(colors.RED)))
Traceback (most recent call last): File
"C:/Users/b-rosard/PycharmProjects/Test/test.py", line 12, in
ws[cell].styles = Style(font=Font(color=Color(colors.RED)))
AttributeError: 'Cell' object has no attribute 'styles'
I was following the example here: http://openpyxl.readthedocs.org/en/latest/styles.html and I have no clue why I'm getting that error
Simple fix after looking at the attributes of Cell.
ws[cell].style = Style(font=Font(color=Color(colors.RED)))
This code worked for me. I am using python 3.x.
from openpyxl.styles import Color, Font, PatternFill
book = Workbook()
output = book.active
cell = output.cell(row = some value, column = some value)
cell.fill = cell.fill.copy(patternType = 'solid', fgColor = 'FFFFFF00')
'FFFFFF00' used for yellow