Problem
Referring to the code below, whenever I run this piece of code, it will find the charts all the sheets and exporting as an image. However, when it comes to chartObject.Chart.Export("chart" + str(i) + ".png") , it always exports to document folder in window.
Question
Is there a way to declare a path for it to be exported? (P.s) I have tried reading the documentation but there is no information regarding to my question. Thanks.
Code
1 thing to note: this piece of code was answered in 1 of the stackoverflow question way back in 2018. Hence, I do not own the credit for it. But I am working on something similar. Thanks.
from win32com.client import Dispatch
app = Dispatch("Excel.Application")
workbook_file_name = 'Programmes.xlsx'
workbook = app.Workbooks.Open(Filename=workbook_file_name)
# WARNING: The following line will cause the script to discard any unsaved changes in your workbook
app.DisplayAlerts = False
i = 1
for sheet in workbook.Worksheets:
for chartObject in sheet.ChartObjects():
# print(sheet.Name + ':' + chartObject.Name)
chartObject.Chart.Export("chart" + str(i) + ".png")
i += 1
workbook.Close(SaveChanges=False, Filename=workbook_file_name)
Solution
Hey guys, sorry for me posting my answer. But after some trial and error, I have figure out the solution
chartObject.Chart.Export("chart" + str(i) + ".png")
Simply add the path along with the file name. Example:
chartObject.Chart.Export(os.getcwd() + "/chart" + str(i) + ".png")
For those who are not sure what is os.getcwd() it basically means the current directory where the file of your code is.
Note: Never use os.path.join() cause you will get an error hence is safe to use as stated above.
Related
I have a python code producing report on xlsx format using openpyxl.
It starts with copying a template to a new file with different name, filling the data on it and finally save it with different name.
the template (which is in xlsx format of course) contains logo, when i run the code in Linux i get the output file with the logo as expected, but when i run the same code in Windows i get the output without the logo!
import openpyxl
import re
import shutil
import os
src = r'/app1/labreport_template.xlsx'
dst = r'/app1/labreport.xlsx'
shutil.copyfile(src, dst)
my_wb=openpyxl.load_workbook("app1/labreport.xlsx")
my_sheet = my_wb.active
##all selections and formatting run here##
##End_Of_Formatting_Output##
my_wb.save("/XP_2600/Reporting_21/labreport.xlsx")
zrc = r'/app1/labreport.xlsx'
dzz = r'/app1/' + idx + '.xlsx'
shutil.copyfile(zrc, dzz)
os.remove(zrc)
print('Successfully generated the report: ' + ' ' + dzz )
Windows version just have Windows paths, everything else still same exact as Linux version, any idea whats wrong ? thanks.
I found a workaround for this by adding this:
##Logo_Entry
logo = openpyxl.drawing.image.Image('logo.png')
logo.anchor = 'A1'
my_sheet.add_image(logo)
##Logo_End
Of course its not a solution, and i still wonder why openpyxl on Windows processing the file like this!,
but i add the workaround, maybe it help someone facing same issue.
I have been getting into Python lately and have come across a problem wich i think i could solve using it.
I have a USB stick with a lot of folders in there, the folders each contain the following:
/HTML5/
/Images/
foldername.html
foldername.ofp
preview.html
profile.xml
Now, i have to create a zip file of each folder, but only containing the Images folder and the profile.xml file. There is 40ish folders in there and there will be more in the future.
Here is the final code:
# Script to zip Foldername/Images/ and Foldername/profile.xml to Foldername.zip
import os
import zipfile
dirname = "D:\\testdir"
for schoen in os.listdir(dirname):
print schoen
myZipFile = zipfile.ZipFile(schoen+".zip", "w" )
for f in os.listdir(os.path.join(dirname, schoen)):
print f
if f == "Profile.xml":
print "Found profile.xml"
myZipFile.write(schoen + "\\" + f, f)
elif f == "Images":
print "Found Images"
myZipFile.write(schoen + "\\" + f, f)
myZipFile.close()
Many thanks,
Grootie
Instead of finding random code and trying to guess what it might mean and what you should change, why not look it up in the documentation?
The parameters to ZipFile.write are:
ZipFile.write(filename, arcname=None, compress_type=None)
So your code copies the file named profile.xml into the archive under the name images\\test.py. Is that really what you want? I doubt it. But I'm not sure what you do want. You need to figure that out, in terms you could explain to an idiot (because computers are idiots). Then the docs—or SO, if you get confused by the docs—can help you translate that explanation into the appropriate code.
The script receives two variables from a previous web page. From those variables, the code determines which images are desired. It sends those images to a temp folder, zips up that folder and places it in an output folder for pickup. That's where things go south. I'm trying to allow the webpage to provide a button for the user to click on and download the zip file. Because the zip file's name needs to change based on the variables the script receives, I cannot just make a generic link to the zip file.
import arcpy, sys, shutil, os
path = "C:/output/exportedData/raw/"
pathZip = "C:/output/exportedData/zip/"
#First arg is the mxd base filename which is the same as the geodatabase name
geodatabaseName = "C:/output/" + sys.argv[1] + ".gdb"
#this is where the images are determined and sent to a folder
zipFileName = sys.argv[1]
zipFile = shutil.make_archive(path + zipFileName,"zip")
movedZip = os.rename(zipFile, pathZip + zipFileName + ".zip")
shutil.rmtree(path + zipFileName)
print """<h3>Download zip file</h3>""".format(movedZip)
And the last line indicates where the problem comes in. Firebug indicates the link made is
Download zip file
The string substitution isn't working in this case and I'm at a loss as to why. Thank you, in advance for any assistance you can provide.
os.rename() doesn't return anything, which means that movedZip becomes None.
Here's what you probably want to do instead:
movedZip = pathZip + zipFileName + ".zip"
os.rename(zipFile, movedZip)
The os.rename method does not return any value. You could see the official document here. It rename the file or directory src to dst. Some exceptions might be thrown. But does not return anything.
I'm currently playing a trading card game called Hearthstone which is made by blizzard. The game is pretty good, but lacks basic features that any game that calls itself "competitive" should have, like stat tracking and replay.
So as I said in the title, I'm trying to create a (very crude and poorly done) script that let's me record every match I play. Due to my lack of programming skills, 80% of the script is just a bunch of code that I borrowed from all sorts of places and adapted to make it do what I wanted.
The idea is to make it work like this:
I take a picture of every turn I play. It might become annoying, but I do not dare to think about implementing OCR as to make the script take a picture at the start of every turn by itself. Would be awesome but I just can't do it...
The game sends every picture to the desktop (no need to code that).
At the end of the game I run the script
2.1 Every match is going to have a numbered folder so the script creates that. The folders are going to be called "Match1", "Match2", etc. You can see how poorly written that is because I made it on my own :P
import sys
import os
import shutil
def checkFolder():
os.path.join('D:\Hearthstone\Replays\Match1')
matchNumber=1
while os.path.exists("D:\\Hearthstone\\Replays\\Match"+ str(matchNumber)) is True:
matchNumber=matchNumber + 1
else:
os.makedirs("D:\Hearthstone\Replays\Match"+str(matchNumber))
2.2 Script sends the photos from Desktop to the recently created folder. The Problem is that I do not know how to make the script change the destination folder to the newest folder created. I did not write this part of the code, i merely adapted it. Source: http://tinyurl.com/srcbh
folder = os.path.join('C:\\Users\\Felipe\\', 'Desktop') # Folder in which the images are in.
destination = os.path.join('D:\\Hearthstone\\Replays\\', 'match9999') #**Destination needs to be the newest folder and I dont know how to implement that...
extmove = 'png' # The extension you wish to organize.
num = 0 # Variable simply to use after to count images.
for filename in os.listdir(folder): #Run through folder.
extension = filename.split(".")[-1] # This strips the extensions ready to check and places into the extension
if extension == extmove: # If statement. If the extension of the file matches the one set previously then..
shutil.move(folder + "\\" + filename, destination) # Move the file from the folder to the destination folder. Also previously set.
num = num + 1
print(num)
print (filename, extension)
And that's it! I need help with step 2.2. I'd certainly appreciate the help!
Now, the reason I made such a big post is because I wanted to expose my idea and hopefully inspire someone to take on a similar project seriously. Hearthstone has thousands of players that could benefit from it, not to mention that this seems to be a fairly easy task to someone with more experience.
Ok, I finally got it to work!
import sys
import os
import shutil
def sendPhotos():
matchNumber=1
photos_dest = "D:\\Hearthstone\\Replays\\Match"
while os.path.exists(photos_dest+ str(matchNumber)): #creates the name of the folder "Match1", "Match2", etc.
matchNumber=matchNumber + 1
else:
photos_destination = photos_dest+str(matchNumber)
os.makedirs(photos_destination)
for files in os.listdir('C:\\Users\\Felipe\\Desktop'):#only png files are moved
if files.endswith(".png"):
shutil.move(files, photos_destination)
sendPhotos()
Thank you to those who gave me some answers! I really appreciated it!
Well, first off, the fact that you identified a problem and put together a solution shows that you certainly don't lack programming skills. Give yourself some credit. You just need more practice. :)
This should be better, I haven't run it, so there might be some errors :P
def checkFunction(base_dir='D:\\Hearthstone\\Replays\\'): #set this as a parameter with a default
match_number = 1
if os.path.exists(base_dir): #if the base directory doesn't exist you'll have a bad time
while os.path.exists(os.path.join(base_dir, 'Match{0}'.format(match_number)))
match_number += 1
new_dir = os.path.join(base_dir, 'Match{0}'.format(match_number))
os.makedirs(new_dir)
return new_dir
For the function checkFolder, I suggest having it return the new directory name (as above). You'll also need to indent all the lines below it so python knows those lines are part of that function (this might just be a formatting issue on SO though).
Then, once the checkFolder function is working properly, all you have the change in 2.2 is:
destination = checkFolder()
This sees which matches are in the folder and takes the lowest number for the folder.
folder = os.path.join('C:\\Users\\Felipe\\', 'Desktop') # Folder in which the images are in.
recorded_matches_location = 'D:\\Hearthstone\\Replays\\'
match_number = 1
match_name = 'match1'
while match_name in os.listdir(recorded_matches_location):
match_number = 1 + match_number
match_name = 'match' + str(match_number) # corrected it! there must be a string and not a variable
destination = os.path.join(recorded_matches_location, match_name) #**Destination needs to be the newest folder and I dont know how to implement that...
extmove = 'png' # The extension you wish to organize.
num = 0 # Variable simply to use after to count images.
for filename in os.listdir(folder): #Run through folder.
extension = filename.split(".")[-1] # This strips the extensions ready to check and places into the extension
if extension == extmove: # If statement. If the extension of the file matches the one set previously then..
shutil.move(folder + "\\" + filename, destination) # Move the file from the folder to the destination folder. Also previously set.
num = num + 1
print(num)
print (filename, extension)
I have a fairly simple python loop that calls a few functions, and writes the output to a file. To do this is creates a folder, and saves the file in this folder.
When I run the program the first time with a unique file name, it runs fine. However, if I try to run it again, it will not work and I do not understand why. I am quite certain that it is not a problem of overwriting the file, as I delete the folder before re-running, and this is the only place that the file is stored. Is there a concept that I am mis-understanding?
The problematic file is 'buff1.shp'. I am using Python 2.5 to run some analysis in ArcGIS
Thanks for any advice (including suggestions about how to improve my coding style). One other note is that my loops currently only use one value as I am testing this at the moment.
# Import system modules
import sys, string, os, arcgisscripting, shutil
# Create the Geoprocessor object
gp = arcgisscripting.create()
# Load required toolboxes...
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Spatial Statistics Tools.tbx")
gp.AddToolbox("C:/Program Files/ArcGIS/ArcToolbox/Toolboxes/Analysis Tools.tbx")
# specify workspace
gp.Workspace = "C:/LEED/Cities_20_Oct/services"
path = "C:\\LEED\\Cities_20_Oct\\services\\"
results = 'results\\'
os.mkdir( path + results )
newpath = path + results
# Loop through each file (0 -> 20)
for j in range(0,1):
in_file = "ser" + str(j) + ".shp"
in_file_2 = "ser" + str(j) + "_c.shp"
print "Analyzing " + str(in_file) + " and " + str(in_file_2)
#Loop through a range of buffers - in this case, 1,2
for i in range(1,2):
print "Buffering....."
# Local variables...
center_services = in_file_2
buffer_shp = newpath + "buff" + str(i) + ".shp"
points = in_file_2
buffered_analysis_count_shp = newpath + "buffered_analysis_count.shp"
count_txt = newpath + "count.txt"
# Buffer size
b_size = 1000 + 1000 * i
b_size_input = str(b_size) + ' METERS'
print "Buffer:" + b_size_input + "\n"
# Process: Buffer...
gp.Buffer_analysis(center_services, buffer_shp, b_size_input, "FULL", "ROUND", "ALL", "")
print "over"
(To clarify this question I edited a few parts that did not make sense without the rest of the code. The error still remains in the program.)
Error message:
ExecuteError: ERROR 000210: Cannot create output C:\LEED\Cities_20_Oct\services\results\buff1.shp Failed to execute (Buffer).
I can't see how the file name in the error message blahblah\buff1.shp can arise from your code.
for i in range(0,1):
buffer_shp = newpath + "buff" + str(i) + ".shp"
gp.Buffer_analysis(center_services, buffer_shp, etc etc)
should produce blahblah\buff0.shp not blahblah\buff1.shp... I strongly suggest that the code you display should be the code that you actually ran. Throw in a print statement just before the gp.Buffer_analysis() call to show the value of i and repr(buffer_shp). Show all print results.
Also the comment #Loop through a range of buffers (1 ->100) indicates you want to start at 1, not 0. It helps (you) greatly if the comments match the code.
Don't repeat yourself; instead of
os.mkdir( path + results )
newpath = path + results
do this:
newpath = path + results # using os.path.join() is even better
os.mkdir(newpath)
You might like to get into the habit of constructing all paths using os.path.join().
You need to take the call to os.mkdir() outside the loops i.e. do it once per run of the script, not once each time round the inner loop.
The results of these statements are not used:
buffered_analysis_count_shp = newpath + "buffered_analysis_count.shp"
count_txt = newpath + "count.txt"
Update
Googling with the first few words in your error message (always a good idea!) brings up this: troubleshooting geoprocessing errors which provides the following information:
geoprocessing errors that occur when
reading or writing ArcSDE/DBMS data
receive a generic 'catch-all' error
message, such as error 00210 when
writing output
This goes on to suggest some ways of determining what your exact problem is. If that doesn't help you, you might like to try asking in the relevant ESRI forum or on GIS StackExchange.
I see this is a 3 year old posting, but for others will add:
As I generate python script to work with Arc, I always include right after my import:
arcpy.env.overwriteOutput=True # This allows the script to overwrite files.
Also you mentioned you delete your "folder"?. That would be part of your directory, and I do not see where you are creating a directory in the script. You would want to clear the folder, not delete it (maybe you meant you delete the file though).
JJH
I'd be tempted to look again at
path = "C:\LEED\Cities_20_Oct\services\"
Surely you want double front slashes, not double back slashes?