I Need to read check boxes and have accomplished using below
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
wb = excel.Workbooks.Open(r'\Test.xlsx')
ws = wb.Worksheets("Sheet1")
cb_dict = {}
for cb in ws.CheckBoxes():
cb_dict[cb.Name] = cb.Value
print(cb_dict)
excel.Application.quit()
The below works fine when called from windows but when this python scripts is called in other OS systems win32 library doesnt seem to be compatible
if anyone have a different approach please share
Unzip the name.xlxs table file to the folder. You'll find a file name/xl/drawings/vmlDrawing1.vml. There is the information including Anchor, Checked. The value of the checkbox in the front of the shape.
We can parse the vmlDrawing1.vml just like parse other XML file. I used xml.etree.ElementTree to find checkbox information in XML.
Reference: https://hypotenuselabs.medium.com/attack-on-checkbox-when-data-ingestion-gets-ugly-999fcdc5e000
Related
I'm trying to create a Python script (I'm using Python 3.7.3 with UTF-8 encoding on Windows 10 64-bit with Microsoft Office 365) that exports user selected worksheets to PDF, after the user has selected the Excel-files.
The Excel-files contain a lot of different settings for page setup and each worksheet in each Excel-file has a different page setup.
The task is therefore that I need to read all current variables regarding page setup to be able to assign them to the related variables for export.
The problem is when I'm trying to get Excel to return the current print area of the worksheet, which I can't figure out.
As far as I understand I need to be able to read the current print area, to be able to set it for the export.
The Excel-files are a mixture of ".xlxs" and ".xlsm".
I've tried using all kind of different methods from the Excel VBA documentation, but nothing has worked so far e.g. by adding ".Range" and ".Address" etc.
I've also tried the ".UsedRange", but there is no significant difference in the cells that I can search for and I can't format them in a specific way so I can't use this.
I've also tried using the "IgnorePrintAreas = False" variable in the "ExportAsFixedFormat"-function, but that didn't work either.
#This is some of the script.
#I've left out irrelevant parts (dialogboxes etc.) just to make it shorter
#Import pywin32 and open Excel and selected workbook.
import win32com.client as win32
excel = win32.gencache.EnsureDispatch("Excel.Application")
excel.Visible = False
wb = excel.Workbooks.Open(wb_path)
#Select the 1st worksheet in the workbook
#This is just used for testing
wb.Sheets([1]).Select()
#This is the line I can't get to work
ps_prar = wb.ActiveSheet.PageSetup.PrintArea
#This is just used to test if I get the print area
print(ps_prar)
#This is exporting the selected worksheet to PDF
wb.Sheets([1]).Select()
wb.ActiveSheet.ExportAsFixedFormat(0, pdf_path, Quality = 0, IncludeDocProperties = True, IgnorePrintAreas = False, OpenAfterPublish = True)
#This closes the workbook and the Excel-file (although Excel sometimes still exists in Task Manager
wb.Close()
wb = None
excel.Quit()
excel = None
If I leave the code as above and try and open a test Excel-file (.xlxs) with a small PrintArea (A1:H8) the print function just gives me a blank line.
If I add something to .PrintArea (as mentioned above) I get 1 of 2 errors:
"TypeError: 'str' object is not callable".
or
"ps_prar = wb.ActiveSheet.PageSetup.PrintArea.Range
AttributeError: 'str' object has no attribute 'Range'"
I'm hoping someone can help me in this matter - thanks, in advance.
try
wb = excel.Workbooks.OpenXML(wb_path)
insead of
wb = excel.Workbooks.Open(wb_path)
My problem was with a german version of ms-office. It works now. Check here https://social.msdn.microsoft.com/Forums/de-DE/3dce9f06-2262-4e22-a8ff-5c0d83166e73/excel-api-interne-namen?forum=officede
So I coded up a program that extracts data from certain websites and then exports said data to a temporary excel file(which is created at the given path if not already existing). Below is the code for the main function. The part I am having trouble with is starting with book = xlwt.Workbook() but I wanted to include everything to provide the full situation. I coded up the program on a Windows 10 computer, and everything worked fine. However, I need to change this to work on a mac. I know with the mac I'm getting to at least the browser.close() part but after that, I have no idea if anything is working. I am unsure if I am writing into an Excel file at all in the first place, but mostly I am having trouble figuring out how to find the path of the excel file and launching the file itself. Can anyone help me figure out how to do the same thing I do below but just for a mac instead??
def main():
now = datetime.datetime.now()
option = selenium.webdriver.ChromeOptions()
browser = selenium.webdriver.Chrome()
keyword = None
urlList = None
# two different lists of data I scrapped
wi = webInfo(browser, keyword)
mi = mobileInfo(browser, keyword)
urlList = wi+mi
browser.close()
book = xlwt.Workbook()
sheet1 = book.add_sheet('sheet1')
for i in range(len(urlList)):
for j in range(len(urlList[i])):
sheet1.write(i, j, urlList[i][j])
name = "random.xls"
book.save(name)
book.save(TemporaryFile())
excelFile = "C:/Users/me/PycharmProjects/test/random.xls"
excelEx = r"C:/Program Files/Microsoft Office/root/Office16/EXCEL"
subprocess.Popen([excelEx, excelFile])
You could use os module to deal with paths in mac if you have limited access to macOS.
For example let's assume that you want to put the output excel file into the same directory as your python file, then,
import os
os.chdir(os.getcwd())
name = "random.xls"
book.save(name)
excelFile = os.path.abspath('random.xls')
# just try without these lines first and open file manually
excelEx = "You need to show the excel executable at this point"
subprocess.Popen([excelEx, excelFile])
I am opening Excel 2016 from Python using the PyWin32 package using the following code
import win32com.client as win32
from win32com.client import Dispatch
def openWorkbook(filePath):
excelObj = win32.gencache.EnsureDispatch("Excel.Application")
excelObj.DisplayAlerts = False
excelObj.Visible = True
wbkObj = excelObj.Workbooks.Open(Filename=filePath)
return(excelObj, wbkObj)
When I open workbooks in this way, a number of the add-ins which I rely upon are not initialized, though they do initialize when I open Excel in the typical fashion.
While I understand that I can initialize them manually via their filepaths, I would much prefer to open Excel in such a way that all of the add-ins which typically initialize are included.
Thank you.
Is there a way, using win32com, to specify that Python only selects/copies/pastes/autofills/etc a range that stops when it reaches an empty cell?
i.e.
Range(A1:A%End)
Certainly open to xlrd library suggestions, but my entire script is already using win32com. Thanks for any tips folks!
import win32com.client as win32
excel = win32.gencache.EnsureDispatch('Excel.Application')
source = excel.Workbooks.Open("C:\source")
excel.Range("A:AA").Select()
excel.Selection.Copy()
copy = excel.Workbooks.Open("C:\copy")
excel.Range("E:AE").Select()
excel.Selection.PasteSpecial()
You can get the last non-emtpy cell via
XlDirectionDown = 4
last = wb.Range("A:A").End(XlDirectionDown)
range = wb.Range("A1:A"+str(last))
The XlDirectionDown is an XlDirection enum item (xlDown), you can also get its value from COM by dispatching via EnsureDispatch:
xlApp = win32com.client.gencache.EnsureDispatch('Excel.Application')
import win32com.client.constants as cc
XlDirectionDown = cc.xlDown
First line builds the type library for Excel for win32com, which makes constants available.
This might be a bit of a stretch, but is there a possibility that a python script can be used to create VBA in MS Excel (or any other MS Office product that uses VBA) using pythonwin or any other module.
Where this idea came from was pythons openpyxl modules inability to do column autowidth. The script I have creates a workbook in memory and eventually saves it to disc. There are quite a few sheets and within each sheet, there are quite a few columns. I got to thinking....what if I just use python to import a VBA script (saved somewhere in notepad or something) into the VBA editor in excel and then run that script from python using pythonwin.
Something like:
Workbooks.worksheets.Columns("A:Z").EntireColumn.Autofit
Before you comment, yes I have seen lots of pythonic examples of how to work around auto adjusting columns in openpyxl, but I see some interesting opportunities that can be had utilizing the functionality you get from VBA that may not be available in python.
Anyways, I dug around the internet a bit and I didn't see anything that indicates i can, so i thought I'd ask.
Cheers,
Mike
Yes, it is possible. You can start looking at how you can generate a VBA macro from VB on that Microsoft KB.
The Python code below is illustrating how you can do the same ; it is a basic port of the first half of the KB sample code:
import win32com.client as win32
import comtypes, comtypes.client
xl = win32.gencache.EnsureDispatch('Excel.Application')
xl.Visible = True
ss = xl.Workbooks.Add()
sh = ss.ActiveSheet
xlmodule = ss.VBProject.VBComponents.Add(1) # vbext_ct_StdModule
sCode = '''sub VBAMacro()
msgbox "VBA Macro called"
end sub'''
xlmodule.CodeModule.AddFromString(sCode)
You can look at the visible automated Excel macros, and you will see the VBAMacro defined above.
The top answer will only add the macro, if you actually want to execute it there is one more step.
import win32com.client as win32
xl = win32.gencache.EnsureDispatch('Excel.Application')
xl.Visible = True
ss = xl.Workbooks.Add()
xlmodule = ss.VBProject.VBComponents.Add(1)
xlmodule.Name = 'testing123'
code = '''sub TestMacro()
msgbox "Testing 1 2 3"
end sub'''
xlmodule.CodeModule.AddFromString(code)
ss.Application.Run('testing123.TestMacro')
Adding a module name will help deconflict from any existing scripts.