Why openpyxl is hidding some rows? - python

I'm having a little trouble with openpyxl. I'm updating an excel with historic data something like this:
The excel has 2 sheets with this data, both are almost the same. The thing is that after I add the new rows and aply the formats, in the second sheet for some reason a lot of row are hidden, like this:
This is my code:
from copy import copy
import pandas as pd
from openpyxl import load_workbook
datos = pd.Dataframe(my_data) # This is not right but I already have the data in a DF
today = datos[col1].loc[0].strftime("%Y-%m-%d")
tomorrow = datos[col1].loc[1].strftime("%Y-%m-%d")
historic = 'my_excel.xlsx'
logger.info('Reading Excel')
wb = load_workbook(historic)
sheets = wb.sheetnames
for sheet in sheets:
logger.warning(f'************* {sheet} *************')
ws = wb[sheet]
logger.info(f'active: {wb.active}')
logger.info(f"len D: {len(ws['D'])}")
logger.info(f"len E: {len(ws['E'])}")
max_row = len(ws['D'])
logger.info('Last D cell')
last_D_cell = ws.cell(row=max_row, column=4)
last_D_cell_value = last_D_cell.value.strftime("%d/%m/%Y")
logger.info('New Cell')
new_D_cell = ws.cell(row=max_row + 1, column=4)
new_D_cell.font = copy(last_D_cell.font)
new_D_cell.border = copy(last_D_cell.border)
new_D_cell.number_format = copy(last_D_cell.number_format)
new_D_cell.alignment = copy(last_D_cell.alignment)
new_D_cell.fill = copy(last_D_cell.fill)
new_D_cell.value = datos[col1].loc[1].strftime("%d/%m/%Y")
logger.info('Penultimate D Cell')
penultimate_D_cell = ws.cell(row=max_row - 1, column=4)
last_D_cell.font = copy(penultimate_D_cell.font)
last_D_cell.border = copy(penultimate_D_cell.border)
last_D_cell.number_format = copy(penultimate_D_cell.number_format)
last_D_cell.alignment = copy(penultimate_D_cell.alignment)
last_D_cell.fill = copy(penultimate_D_cell.fill)
logger.info('Last E Cell')
last_E_cell = ws[f'E{max_row}']
new_E_cell = ws.cell(row=max_row + 1, column=5)
new_E_cell.font = copy(last_E_cell.font)
new_E_cell.border = copy(last_E_cell.border)
new_E_cell.number_format = copy(last_E_cell.number_format)
new_E_cell.alignment = copy(last_E_cell.alignment)
new_E_cell.fill = copy(last_E_cell.fill)
new_E_cell.value = tomorrow_value
logger.info('Penultimate E')
penultimate_E_cell = ws[f'E{max_row - 1}']
last_E_cell.font = copy(penultimate_E_cell.font)
last_E_cell.border = copy(penultimate_E_cell.border)
last_E_cell.number_format = copy(penultimate_E_cell.number_format)
last_E_cell.alignment = copy(penultimate_E_cell.alignment)
last_E_cell.fill = copy(penultimate_E_cell.fill)
logger.info('SAving Excel')
wb.save(historic)
With this code, the last sheet it works will have the hidden rows, and I don't know why is this happening.
Hope someone can help me thanks
EDIT: I'm on Ubuntu 20.4 LTS, and the resulting files has been opened in both Ubuntu and Windows 10 and the same situation appears.

Related

I can't get the accurate numbers on the web table

import requests
import bs4
from tkinter import *
def statno():
covidTk = Tk()
covidTk.title('Data statistics of COVID-19')
web = requests.get('https://www.worldometers.info/coronavirus')
objSoup = bs4.BeautifulSoup(web.text,'lxml')
lb1 = Label(covidTk,text='Country: ')
lb1.grid(row=1,column=0,padx=10,pady=10)
lb2 = Label(covidTk,text=entcon.get())
lb2.grid(row=1,column=1,padx=10,pady=10)
table = objSoup.find('table',attrs={'id':'main_table_countries_today'})
headings = [th.get_text() for th in table.find('tr').find_all('th')]
set_of_datas = []
for row in table.find_all('tr')[1:]:
data = dict(zip(headings,(td.get_text() for td in row.find_all('td'))))
set_of_datas.append(data)
print(set_of_datas)
win = Tk()
win.title('COVID-19 tracker')
web = requests.get('https://www.worldometers.info/coronavirus')
objSoup = bs4.BeautifulSoup(web.text,'lxml')
lbtitle = Label(win,text='Covid-19 Statistics')
lbtitle.grid(row=0,columnspan=2)
lbcon = Label(win,text='Country: ')
lbcon.grid(row=1,column=0,padx=10,pady=20)
conname = StringVar()
entcon = Entry(win,textvariable=conname)
entcon.grid(row=1,column=1,padx=10,pady=20)
btncheck = Button(win,text='Check data',command=statno)
btncheck.grid(row=2,column=1,padx=10,pady=10)
lbcase = Label(win,text='Coronavirus Cases: ')
lbcase.grid(row=3,column=0)
total = objSoup.find_all('div',{'class':'maincounter-number'})
total_cases = total[0]
lbdat1 = Label(win,text=total_cases.text)
lbdat1.grid(row=3,column=1)
lbdeaths = Label(win,text='Deaths: ')
lbdeaths.grid(row=4,column=0)
total_deaths = total[1]
lbdat2 = Label(win,text=total_deaths.text)
lbdat2.grid(row=4,column=1)
lbcase = Label(win,text='Recovered: ')
lbcase.grid(row=5,column=0)
total_recover = total[2]
lbdat3 = Label(win,text=total_recover.text)
lbdat3.grid(row=5,column=1)
When I print(set_of_datas) the values come out are not encoded well. Any methods to make the value appear without garbled strings? I may want to ask do I need to use intersecting of rows and columns? How to refer the data by using the table of the country with the number statistics together? Because I do not know how to get the corresponding datas if I type the country name and clicked the button. Can any people teach me the method to refer data in the table?

How to insert a real pivot table in a excel sheet with python?

I want to create a "real" pivot table in excel sheet with python without using the function of pandas (pandas.pivot_table).
Is there a method?
I need to create the "true" pivot table in excel with a dropdown combo box. Unfortunately the pandas pivot is static (is a table) and not dynamic.
Can anyone help me?
Can you try it this way?
import win32com.client
Excel = win32com.client.gencache.EnsureDispatch('Excel.Application') # Excel = win32com.client.Dispatch('Excel.Application')
win32c = win32com.client.constants
wb = Excel.Workbooks.Add()
Sheet1 = wb.Worksheets("Sheet1")
TestData = [['Country','Name','Gender','Sign','Amount'],
['CH','Max' ,'M','Plus',123.4567],
['CH','Max' ,'M','Minus',-23.4567],
['CH','Max' ,'M','Plus',12.2314],
['CH','Max' ,'M','Minus',-2.2314],
['CH','Sam' ,'M','Plus',453.7685],
['CH','Sam' ,'M','Minus',-53.7685],
['CH','Sara','F','Plus',777.666],
['CH','Sara','F','Minus',-77.666],
['DE','Hans','M','Plus',345.088],
['DE','Hans','M','Minus',-45.088],
['DE','Paul','M','Plus',222.455],
['DE','Paul','M','Minus',-22.455]]
for i, TestDataRow in enumerate(TestData):
for j, TestDataItem in enumerate(TestDataRow):
Sheet1.Cells(i+2,j+4).Value = TestDataItem
cl1 = Sheet1.Cells(2,4)
cl2 = Sheet1.Cells(2+len(TestData)-1,4+len(TestData[0])-1)
PivotSourceRange = Sheet1.Range(cl1,cl2)
PivotSourceRange.Select()
Sheet2 = wb.Worksheets(2)
cl3=Sheet2.Cells(4,1)
PivotTargetRange= Sheet2.Range(cl3,cl3)
PivotTableName = 'ReportPivotTable'
PivotCache = wb.PivotCaches().Create(SourceType=win32c.xlDatabase, SourceData=PivotSourceRange, Version=win32c.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=PivotTargetRange, TableName=PivotTableName, DefaultVersion=win32c.xlPivotTableVersion14)
PivotTable.PivotFields('Name').Orientation = win32c.xlRowField
PivotTable.PivotFields('Name').Position = 1
PivotTable.PivotFields('Gender').Orientation = win32c.xlPageField
PivotTable.PivotFields('Gender').Position = 1
PivotTable.PivotFields('Gender').CurrentPage = 'M'
PivotTable.PivotFields('Country').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Country').Position = 1
PivotTable.PivotFields('Country').Subtotals = [False, False, False, False, False, False, False, False, False, False, False, False]
PivotTable.PivotFields('Sign').Orientation = win32c.xlColumnField
PivotTable.PivotFields('Sign').Position = 2
DataField = PivotTable.AddDataField(PivotTable.PivotFields('Amount'))
DataField.NumberFormat = '#\'##0.00'
Excel.Visible = 1
wb.SaveAs('ranges_and_offsets.xlsx')
Excel.Application.Quit()
https://www.yinglinglow.com/blog/2018/04/29/xlwings-pivot-table
Here is another way using xlwings.
import xlwings as xw
from xlwings import constants
# create instance of Excel app
app = xw.App(visible=True)
# create workbook object
wb = app.books.open('my_file') # where my_file is in .xlsx format
# create sheet object
sht = wb.sheets['my_sheet_name'] # where my_sheet_name is name of your Excel sheet name that contains your data
# determine last row and column of your data
num_col = sht.range('A1').end('right').column
num_row = sht.range('A1').end('down').row
# define your pivot table data range
PivotSourceRange = sht.range((1,1), (num_row, num_col))
# add a pivot sheet to your Excel file
xw.sheets.add(name='pivot', before='my_sheet_name')
# name your pivot table
PivotTableName = 'MyPivotTable'
pivot_tab_name = '' + 'pivot' + '!R1C1'
# create pivot table cache
PivotCache = wb.api.PivotCaches().Create(SourceType=constants.PivotTableSourceType.xlDatabase,
SourceData=PivotSourceRange.api,
Version=constants.PivotTableVersionList.xlPivotTableVersion14)
PivotTable = PivotCache.CreatePivotTable(TableDestination=pivot_tab_name,
TableName=PivotTableName,
DefaultVersion=constants.PivotTableVersionList.xlPivotTableVersion14)
# structure the pivot table
PivotTable.PivotFields('your_row_label').Orientation = constants.PivotFieldOrientation.xlRowField
PivotTable.PivotFields('your_page_label').Orientation = constants.PivotFieldOrientation.xlPageField
DataField = PivotTable.AddDataField(PivotTable.PivotFields('the_column_you_want_to_tabulate'))
DataField.Function = constants.TotalsCalculation.xlTotalsCalculationAverage
# other available calculation methods include:
# .xlTotalsCalculationCountNums
# .xlTotalsCalculationMax
# .xlTotalsCalculationMin
# .xlTotalsCalculationNone
# .xlTotalsCalculationCount
# .xlTotalsCalculationCustom
# .xlTotalsCalculationStdDev
# .xlTotalsCalculationSum
# .xlTotalsCalculationVar
# you specify the formatting of your numbers with this statement
DataField.NumberFormat = '0.0' # which uses standard Excel formats
# finish building the pivot table
PivotTable.PivotFields('your_page_label').EnableMultiplePageItems = True
PivotTable.PivotFields('your_page_label').PivotItems().Visible = True
End result is something like this:

Python / Excel Automation - Text from 2 cells into 1 cell

I'm using python to automate the process of creating multiple name tags using an excel sheet list.
My problem is that I need to take the 'name' column and 'enterprise' column values ​​and put them in a single cell of a new document.
Like this:
To this:
Right now I'm using openpyxl and although I manage to transfer one of the columns I can't do it with both.
The code below was one of the things that I've tried.
import openpyxl as xl
e = xl.load_workbook('etiquetas.xlsx')
eplan = e['Planilha1']
c = xl.load_workbook('Crachá Relação 15.10.19.xlsx')
cplan = c['Plan1']
maxlinhas = cplan.max_row
for i in range (2, maxlinhas+1):
nome = cplan.cell(row = i, column = 1).value
preenchernome = eplan.cell(row = i-1, column = 1)
empresa = cplan.cell(row=i, column=2).value
preencherempresa = eplan.cell(row=i - 1, column=1)
preenchernome.value = nome, empresa
e.save('teste.xlsx')
But this code returns the following error:
ValueError: Cannot convert ('Gladisson Garcia Westphal', 'Agro Divel') to Excel
As per the docs preenchernome.value can only have one value
try to use this
preenchernome.value = '{}\n{}'.format(nome, empresa)
The value, that is passed on the target cell should be a single string. Thus:
wksTarget.cell(row = i, column = 1).value = '{}\n{}'.format(name, family)
should be ok. This is the whole code, that worked for me:
import openpyxl as xl
import os
wbSource = xl.load_workbook(os.path.dirname(os.path.realpath(__file__)) + '\myExcel.xlsx')
wksSourse = wbSource['Sheet1']
wbTarget = xl.load_workbook(os.path.dirname(os.path.realpath(__file__)) + '\Target.xlsx')
wksTarget = wbTarget['Sheet1']
for i in range (1, wksSourse.max_row+1):
name = wksSourse.cell(row = i, column = 1).value
family = wksSourse.cell(row = i, column = 2).value
wksTarget.cell(row = i, column = 1).value = '{}\n{}'.format(name, family)
wbTarget.save(os.path.dirname(os.path.realpath(__file__)) + '\Target.xlsx')
wbTarget.close()

py to exe : failed to execute script pyi_rth_win32comgenpy

I'm creating a simple calculation program using tkinter module and want to convert to exe as I want it to be executable at any pc. But somehow the error message show (failed to execute script pyi_rth_win32comgenpy).
I've try used pyinstaller ( cmd and the one on GitHub at : https://github.com/brentvollebregt/auto-py-to-exe) but to no avail. I also try using both types of python file (.py and .pyw)
from tkinter import *
from tkinter.filedialog import askopenfilename
import pandas as pd
from tkinter import messagebox
from pandastable import Table, TableModel
class Window(Frame):
def __init__(self, master =None):
Frame.__init__(self, master)
self.master = master
self.init_window()
def init_window(self):
self.master.title('GUI')
self.pack(fill=BOTH, expand=1)
quitButton = Button(self, text='quit', command=self.client_exit)
quitButton.place(x=0, y=230)
# fileButton = Button(self, text='Browse Data Set', command=self.import_data)
# fileButton.place(x=150, y=0)
fileButton = Button(self, text='SBO', command=self.sbo)
fileButton.place(x=200, y=50)
fileButton = Button(self, text='CBO', command=self.cbo)
fileButton.place(x=150, y=50)
# menu = Menu(self.master)
# self.master.config(menu=menu)
#
# file = Menu(menu)
# file.add_command(label='Save',command=self.client_exit)
# file.add_command(label='Exit', command= self.client_exit)
# menu.add_cascade(label='File', menu=file)
#
# edit = Menu(menu)
# edit.add_command(label='Undo')
# menu.add_cascade(label='Edit', menu=edit)
def client_exit(self):
exit()
# def import_data(self):
#
# csv_file_path = askopenfilename()
# # print(csv_file_path)
# df = pd.read_excel(csv_file_path)
# return df
def sbo(self):
csv_file_path = askopenfilename()
df = pd.read_excel(csv_file_path)
data = df.drop(df.index[0]) # remove first row
data['BOVal%'] = data['BOVal%'].astype(str) # convert to string
data['BOQty%'] = data['BOQty%'].astype(str)
data['CustomerPONo'] = data['CustomerPONo'].astype(str)
data['OrdNo'] = data['OrdNo'].astype(str)
data['VendorNo'] = data['VendorNo'].astype(str)
pivot = data.pivot_table(index='Style', aggfunc='sum') # first pivot
pivoted = pd.DataFrame(pivot.to_records()) # flattened
pivoted = pivoted.sort_values(by=['BOVal'], ascending=False) # sort largest to smallest
pivoted['Ranking'] = range(1, len(pivoted) + 1) # Ranking
cols = pivoted.columns.tolist()
cols = cols[-1:] + cols[:-1]
pivoted = pivoted[cols]
pivoted = pivoted.set_index('Ranking')
col = df.columns.tolist()
col = (col[22:23] + col[15:17] + col[:14] + col[17:22] + col[23:37]) # rearrange column
data = df[col]
data = data.sort_values(by=['BOVal'], ascending=False) # sort value
data['Ranking'] = range(1, len(data) + 1) # Set rank
colm = data.columns.tolist()
colm = colm[-1:] + colm[:-1] # rearrange rank column
data = data[colm]
data = data.set_index('Ranking')
# sumboval = data['BOVal'].sum()
# sumboqty = data['BOQty'].sum()
# rounded = sumboval.round()
dates = data['SnapShotDate']
# print(dates)
dates = dates.iloc[1].strftime('%d%m%Y')
sos = data['SOS']
sos = sos[2]
result = pivoted.iloc[:10, :3]
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('%s SBO %s .xlsx' % (sos, dates), engine='xlsxwriter')
# Write each dataframe to a different worksheet.
result.to_excel(writer, sheet_name='pivot')
df.to_excel(writer, sheet_name=dates)
data.to_excel(writer, sheet_name='SBO')
# Close the Pandas Excel writer and output the Excel file.
writer.save()
messagebox.showinfo("Note", "Calculation Completed")
def cbo(self):
csv_file_path = askopenfilename()
Stylemat = askopenfilename()
df = pd.read_excel(csv_file_path)
sm = pd.read_excel(Stylemat)
df = df.drop(df.index[0])
df.insert(loc=8, column='PH', value=['' for i in range(df.shape[0])])
df.insert(loc=9, column='Site', value=['' for i in range(df.shape[0])])
df['Region'] = df['Region'].fillna('"NA"')
df['S&OP Style Aggrt'] = df['S&OP Style Aggrt'].astype(str)
sm['Style'] = sm['Style'].astype(str)
dates = df['Date_Rp']
# print(dates)
dates = dates.iloc[1]
w = list(dates)
w[1] = '-'
w[3] = '-'
temp = w[0]
w[0] = w[2]
w[2] = temp
dates = "".join(w)
rowcount = len(df)
rowstyle = len(sm)
i = 0
j = 0
Style = []
for i in range(rowcount):
for j in range(rowstyle):
if df.iloc[i, 7] == sm.iloc[j, 0]:
df.iloc[i, 8] = 'Horizon'
df.iloc[i, 9] = sm.iloc[j, 2]
table = pd.pivot_table(df[df.PH == 'Horizon'], index='S&OP Style Aggrt', columns='Region',
values='Net CBO Value', aggfunc='sum')
table['Grand Total'] = table.sum(axis=1)
table = table.sort_values(by=['Grand Total'], ascending=False)
table['Ranking'] = range(1, len(table) + 1)
# Create a Pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('CBO %s .xlsx' % dates, engine='xlsxwriter')
# Write each dataframe to a different worksheet.
table.to_excel(writer, sheet_name='pivot')
df.to_excel(writer, sheet_name=dates)
sm.to_excel(writer, sheet_name='StyleMat')
# Close the Pandas Excel writer and output the Excel file.
writer.save()
messagebox.showinfo("Note", "Calculation Completed")
root = Tk()
root.geometry('400x300')
app = Window(root)
root.mainloop()
I'd like to know how to find the main reason for this error and where to look for it, is it either my scripting method is incorrect or is there any additional file or module that I need. Appreciate in advance for your help. Thank you
I uninstalled everything related to win32 (pypiwin32, pywin32, pywin32-ctypes, pywinpty) and then installed again and magically it worked.
Took the idea from here and here.
this is quite late, but the answer to that issue is just the py to exe cannot execute on numpy 1.17. after downgrade to numpy 1.16, the program can run normally.
You are getting this error failed to execute script pyi_rth_win32comgenpy as result of not including the images you used for you icons and labels
I included images of icon, Question mark and the title
copy this images and include it the directory you have your pyi_rth_win32comgenpy executable.

Can't create a new sheet in GoogleColab and make calculcation

I have an xlsx file on my computer with initial data (value) - two sheets were created. I decide to calculate some value in sheet1 and in sheet2. After this I try to save the result, but when I download a file from GoogleColab and get my start file with initial values.
And I don't know how to creat a new Sheet3 and make this calcuation in it: copy one column from Sheet1 and another column Sheet2 and make P_roz = P_nav + P-osvit the result in a new column in Sheet3.
How to download the xlsx file with the result in picture 2 and picture 4?
from google.colab import drive
drive.mount('/content/gdrive')
!pip install -q xlrd
import pandas as pd
import numpy as np
# Works with Sheet1
df_1 = pd.read_excel('my_path', name_sheet = 'Sheet1')
df_1['T_potyz'] = round((((1 / df_1['K_potyz']**2) - 1))**(1/2.0),3)
df_1['P_nav, кВт'] = df_1['P_ust, кВт']\
* df_1['K_poputy1']
df_1['Q_nav, кВАр'] = round(df_1['P_ust, кВт']\
* df_1['T_potyz'],3)
df_1['S_nav, кВА'] = round((df_1['P_nav, кВт']**2\
+ df_1['Q_nav, кВАр']**2)\
**(1/2.0),3)
df_1['P_nav, кВт'].sum(), df_1['Q_nav, кВАр'].sum(), df_1['S_nav, кВА'].sum()
sum_row1 = df_1[['P_nav, кВт', 'Q_nav, кВАр', 'S_nav, кВА']].sum()
sum_row1
# transpose the data and convert the Series to a DataFrame so that it is easier to concat onto our existing data.
#The T function allows us to switch the data from being row-based to column-based.
df_sum1 = pd.DataFrame(data = sum_row1).T
df_sum1
# to add the missing columns.
df_sum1 = df_sum1.reindex(columns = df_1.columns)
df_sum1
# add it to our existing one using append.
df_final_1 = df_1.append(df_sum1, ignore_index = True)
df_final_1.tail()
# Works with Sheet2
df_2 = pd.read_excel('my_path', sheet_name='Sheet2')
K_po = float(input("Коефіцієнт попиту загально освітлення: "))
df_2['P_ust'] = (round(df_2['k'] * df_2['P_put'] * 10**-3 *
df_2['A, м'] * df_2['B, м'],3))
df_2['P_osvit'] = round(K_po * df_2['P_ust'],3)
df_2['T_potyz2'] = round((((1 / df_2['K_poputy2']**2) - 1))**(1/2.0),3)
df_2['Q_osvit'] = round(df_2['P_osvit'] * df_2['T_potyz2'],3)
df_2['S_osvit'] = round((df_2['P_osvit']**2\
+ df_2['Q_osvit']**2)\
**(1/2.0),3)
df_2['P_osvit'].sum(), df_2['Q_osvit'].sum(), df_2['S_osvit'].sum()
sum_row2 = df_2[['P_osvit', 'Q_osvit', 'S_osvit']].sum()
sum_row2
df_sum2 = pd.DataFrame(data = sum_row2).T
df_sum2
df_sum2 = df_sum2.reindex(columns = df_2.columns)
df_sum2
df_final2 = df_2.append(df_sum2, ignore_index = True)
df_final2.tail()
# Here I want create a new Sheet3 and make some calculation
P_roz = df_1['P_nav, кВт'] + df_2['P_osvit']
Q_roz = df_1['Q_nav, кВАр'] + df_2['Q_osvit']
S_roz = (P_roz**2 + Q_roz**2)**(1 / 2.0)
frame_data3 = {'P_roz' : [P_roz], 'Q_roz' : [Q_roz], 'S_roz' : [S_roz]}
df_4 = pd.DataFrame(frame_data3)
df_4
Sheet 1 Sheet 1 + sum Sheet 2 Sheet 2 + sum

Categories

Resources