How to paste special in excel with python - python

So I am trying to copy alot of data from one woorkbook to another. The thing is that the data in the source workbook has some weird formating so I want to just get the values. The code I have so far is this.
excel=win32com.client.Dispatch("Excel.Application");
excel.Visible = 1;
source = excel.Workbooks.Open(Cali.xlsm');
copy = excel.Workbooks.Open(temp.xlsx');
sdata = source.ActiveSheet;cdata = copy.ActiveSheet;
data=sdata.Range("89:89")
sdata.Range("89:89",data.End(4)).Copy()
now I can use
cdata.Paste()
but it pastes the formating as well
I found
cdata.PasteSpecial()
but it also pastes the formating.
Anyone who know how to use PasteSpecial() so it copies just the values or someone knows a better way I would be very apprecitave.

You could try the following which copies values from cells A1:A3 from one workbook to another.
from win32com.client import Dispatch
wkbk1 = "...\workbook1.xlsx"
wkbk2 = "...\workbook2.xlsx"
excel = Dispatch("Excel.Application")
excel.Visible = 1
source = excel.Workbooks.Open(wkbk1)
excel.Range("A1:A3").Select()
excel.Selection.Copy()
copy = excel.Workbooks.Open(wkbk2)
excel.Range("A1:A3").Select()
excel.Selection.PasteSpecial(Paste=-4163)
wkbk1 and wkbk2 are file paths to two workbooks.

Related

Why is openpyxl keep corrupting my excel files?

I'm trying to apply styles to cells in my excel files using the openpyxl library. If I try this (using an existing style and modifying it):
import openpyxl
wkbk = openpyxl.load_workbook('example.xlsx')
views_sheet = wkbk['Sheet']
cell_ = views_sheet.cell(row=4,column=3)
cell_.style = '20 % - Accent1'
bd = openpyxl.styles.Side(color=openpyxl.styles.colors.Color(theme=29))
cell_.border = openpyxl.styles.Border(left=bd, top=bd, right=bd, bottom=bd)
cell_.font = openpyxl.styles.Font(name='Calibri',size=11,bold=False,italic=False,vertAlign=None,underline='none',strike=False)
wkbk.save('example.xlsx')
I open 'example.xlsx' I get that my file is corrupted/needs to be restored. I thought that maybe it isn't possible writing over some existing style, so I created a new named style "highlight" with the associated color:
highlight = openpyxl.styles.NamedStyle(name="highlight")
highlight.fill = openpyxl.styles.PatternFill(bgColor=openpyxl.styles.colors.Color(theme=30),fill_type='shaded',patternType='lightGray')
bd = openpyxl.styles.Side(color=openpyxl.styles.colors.Color(theme=29))
highlight.border = openpyxl.styles.Border(left=bd, top=bd, right=bd, bottom=bd)
highlight.font = openpyxl.styles.Font(name='Calibri',size=11,bold=False,italic=False,vertAlign=None,underline='none',strike=False)
wkbk.add_named_style(highlight)
cell_.style = 'highlight'
But then I keep getting a ValueError indicating that I need to provide a value for parameter 'patternType' of class 'PatternFill'. This clearly does not makes sense.
Maybe I'm doing this wrong (it's hard to follow the documentation; had to look up older analogous implementations/snippets). Would appreciate some help.
Thank you!
I realize this is very late, but I had a similar issue where openpyxl was corrupting my .xlsx files when I tried to write a Pandas dataframe to an Excel workbook. The issue turned out to be that the workbook had some other tabs with formulas in certain cells, and for some reason the formulas get corrupted when openpyxl runs. I don't understand why, but the "fix" is to remove the formulas (so, hardcode anything you can).

Is there a way to save data in named Excel cells using Python?

I have used openpyxl for outputting values in Excel in my Python code. However, now I find myself in a situation where the cell locations in excel file may change based on the user. To avoid any problems with the program, I want to name the cells where the code can save the output to. Is there any way to have Python interact with named ranges in Excel?
For a workbook level defined name
import openpyxl
wb = openpyxl.load_workbook("c:/tmp/SO/namerange.xlsx")
ws = wb["Sheet1"]
mycell = wb.defined_names['mycell']
for title, coord in mycell.destinations:
ws = wb[title]
ws[coord] = "Update"
wb.save('updated.xlsx')
print("{} {} updated".format(ws,coord))
I was able to find the parameters of the named range using defined_names. After that I just worked like it was a normal Excel cell.
from openpyxl import load_workbook
openWB=load_workbook('test.xlsx')
rangeDestination = openWB.defined_names['testCell']
print(rangeDestination)
sheetName=str(rangeDestination.attr_text).split('!')[0]
cellName = str(rangeDestination.attr_text).split('!')[1]
sheetToWrite=openWB[sheetName]
cellToWrite=sheetToWrite[cellName]
sheetToWrite[cellName]='TEST-A3'
print(sheetName)
print(cellName)
openWB.save('test.xlsx')
openWB.close()

How to filter in Excel using Python?

I am trying to automate a macro-enabled Excel workbook process using Python. I would like to use win32com if possible but am open to switching to other libraries if needed.
Once I get the workbook open and on the sheet I need, there is data already there with auto-filters applied. I just need to filter on a column to make the data available to the macro when I run it.
I use wb.RefreshAll() to import the data from existing connections. Eventually I will need to pass a value entered by the user to the filter as it will be different each time the automation runs.
Most solutions involve copying select data to a Pandas DataFrame etc. but I need the filtered data to remain in the sheet so it can be used by the macro.
I recently wrote a Python script to automate Macros. Basically, the idea was to batch-edit a collection of .doc files and have a macro run for all of them, without having to open them one by one.
First:
What is this macro you want to run?
Second:
What is the data that you need to make visible, and what do you mean by that?
To get you started, try this:
data = [{"test1": 1, "test2": 2}, {"test1": 3, "test2": 4}]
import win32com.client as win32
def openExcel():
xl = win32.gencache.EnsureDispatch('Excel.Application')
wb = xl.Workbooks.Add()
#wb = xl.Workbooks.Open(filepath)
ws = wb.Sheets(1) #The worksheet you want to edit later
xl.Visible = True
return ws
def print2Excel(datapoint:dict, ws):
print(datapoint)
const = win32.constants #.Insert()-Methods keywargs are packaged into const.
ws.Range("A1:B1").Insert(const.xlShiftDown, const.xlFormatFromRightOrBelow)
ws.Cells(1,1).Value = datapoint["test1"]
ws.Cells(1,2).Value = datapoint["test2"]
ws = openExcel() #<- When using Open(filepath), pass the whole filepath, starting at C:\ or whatever drive.
for datapoint in data:
print2Excel(datapoint, ws)
This showcases some of the basics on how to work with Excel objects in win32com

Find words with underscores in excel worksheet by using Python

Is it possible to search/ parse through two columns in excel (let's say columns C & D) and find only the fields with underscores by using python?
Maybe a code like this? Not too sure..:
Import xl.range
Columns = workbook.get("C:D"))
Extract = re.findall(r'\(._?)\', str(Columns)
Please let me know if my code can be further improved on! :)
for those who need an answer, I solved it via using this code:
import openpyxl
from openpyxl.reader.excel import load_workbook
dict_folder = "C:/...../abc"
for file in os.listdir(dict_folder):
if file.endswith(".xlsx"):
wb1 = load_workbook(join(dict_folder, file), data_only = True)
ws = wb1.active
for rowofcellobj in ws["C" : "D"]:
for cellobj in rowofcellobj:
data = re.findall(r"\w+_.*?\w+", str(cellobj.value))
if data != []:
fields = data[0]
fieldset.add(fields)
Yes, it is indeed possible. The main lib you'll get to for that is pandas. With it installed (instructions here) after, of course, installing python, you could do something along the lines of
import pandas as pd
# Reading the Excel worksheet into a pandas.DataFrame type object
sheet_path = 'C:\\Path\\to\\excel\\sheet.xlsx'
df = pd.read_excel(sheet_path)
# Using multiple conditions to find column substring within
underscored = df[(df['C'].str.contains('_')) | (df['D'].str.contains('_'))]
And that'd do it for columns C and D within your worksheet.
pandas has got a very diverse documentation, but to the extent you're looking for, the read_excel function documentation (has examples) will suffice, along with some more content on python itself, if needed.

Python: Write a dataframe to an already existing excel which contains a sheet with images

I have been working on this for too long now. I have an Excel with one sheet (sheetname = 'abc') with images in it and I want to have a Python script that writes a dataframe on a second separate sheet (sheetname = 'def') in the same excel file. Can anybody provide me with some example code, because everytime I try to write the dataframe, the first sheet with the images gets emptied.
This is what I tried:
book = load_workbook('filename_of_file_with_pictures_in_it.xlsx')
writer = pd.ExcelWriter('filename_of_file_with_pictures_in_it.xlsx', engine = 'openpyxl')
writer.book = book
x1 = np.random.randn(100, 2)
df = pd.DataFrame(x1)
df.to_excel(writer, sheet_name = 'def')
writer.save()
book.close()
It saves the random numbers in the sheet with the name 'def', but the first sheet 'abc' now becomes empty.
What goes wrong here? Hopefully somebody can help me with this.
Interesting question! With openpyxl you can easily add values, keep the formulas but cannot retain the graphs. Also with the latest version (2.5.4), graphs do not stay. So, I decided to address the issue with
xlwings :
import xlwings as xw
wb = xw.Book(r"filename_of_file_with_pictures_in_it.xlsx")
sht=wb.sheets.add('SheetMod')
sht.range('A1').value = np.random.randn(100, 2)
wb.save(r"path_new_file.xlsx")
With this snippet I managed to insert the random set of values and saved a new copy of the modified xlsx.As you insert the command, the excel file will automatically open showing you the new sheet- without changing the existing ones (graphs and formulas included). Make sure you install all the interdependencies to get xlwings to run in your system. Hope this helps!
You'll need to use an Excel 'reader' like Openpyxl or similar in combnination with Pandas for this, pandas' to_excel function is write only so it will not care what is inside the file when you open it.

Categories