I'm using a pre-filled Excel range to overwrite it with editpyxl. I saw that openpyxl and xlsxwriter are not able (yet) to keep shapes etc. in other sheets when another sheet is written.
And editpyxl takes a lot of time to write to the Excel range. However, it also blocks the application so I'm trying to make it asynchronous, but wasn't able yet as using await doesn't just work out of the box like magic..
from fastapi import FastAPI, Request
from fastapi.responses import FileResponse
import editpyxl
app = FastAPI()
temp_folder = "./_temp"
file_output_name = "output_fileresponse.xlsx"
#app.get("/my-projects/{project}/download-report", include_in_schema=False)
async def my_project(request: Request,
project: str, ):
report_template = Path(path, excel_file)
wb = editpyxl.Workbook()
wb.open(report_template)
ws = wb.active
def write_pd_to_xlsx(xlsx_range, pd_series):
ss = ws.cells_in_range(xlsx_range)
sc = df[pd_series]
zipped_lists = zip(ss, sc)
for xlsx_cell, pd_value in zipped_lists:
ws.cell(xlsx_cell).value = pd_value
total_records = 2000
ranges_excel_file = [f"C8:C{total_records + 7}", f"D8:D{total_records + 7}",
f"E8:E{total_records + 7}", f"F8:F{total_records + 7}",]
columns_to_use = ["Column 1", "Column 2", "Column 3", "Column 4"]
zipped_ranges_columns = zip(ranges_excel_file, columns_to_use)
for rng, col in zipped_ranges_columns:
write_pd_to_xlsx(rng, col)
wb.save(os.path.join(temp_folder, file_output_name))
response = FileResponse(os.path.join(temp_folder, file_output_name), filename=file_output_name)
wb.close()
return response
Related
I made a GUI Application which looks like this:
The ones marked red are Tkinter Text widgets and the ones marked yellow are Tkinter Entry widgets
After taking user input, the data is to be added to a PSD file and then rendered as an image. But Lets say, after taking the following data as input:
It renders the following Photoshop file:
How do I fix this issue that it does not recognize "\n" properly and hence the rendered document is rendered useless.
Here is the code which deals with converting of the accepted user data into strings and then adding it to Photoshop template and then rendering it:
def DataAdder2CSV():
global edate, eSNO, eage, egender, ename, ePID, econtact, ecomp, eallergy, ehistory, eR
e=edate.get()
a=eSNO.get()
d=eage.get()
f=egender.get()
b=ename.get()
c=ePID.get()
g=econtact.get()
h=ecomp.get(1.0,END)
i=eallergy.get(1.0,END)
j=ehistory.get(1.0,END)
k=eR.get(1.0,END)
data=[a,b,c,d,e,f,g,h,i,j,k]
file=open("Patient_Data.csv","a", newline="")
writer=csv.writer(file, delimiter=",")
writer.writerow(data)
file.close()
messagebox.showinfo("Prescription Generator", "Data has been saved to the database successfully!")
import win32com.client, os
objShell = win32com.client.Dispatch("WScript.Shell")
UserDocs = objShell.SpecialFolders("MyDocuments")
from tkinter import filedialog
ExpDir=filedialog.askdirectory(initialdir=UserDocs, title="Choose Destination Folder")
psApp = win32com.client.Dispatch("Photoshop.Application")
psApp.Open("D:\Coding\Python Scripts\Dr Nikhil Prescription App\Prescription Generator\Presc_Template.psd")
doc = psApp.Application.ActiveDocument
lf1 = doc.ArtLayers["name"]
tol1 = lf1.TextItem
tol1.contents = b
lf2 = doc.ArtLayers["age"]
tol2 = lf2.TextItem
tol2.contents = d
lf3 = doc.ArtLayers["gender"]
tol3 = lf3.TextItem
tol3.contents = f
lf4 = doc.ArtLayers["pid"]
tol4 = lf4.TextItem
tol4.contents = c
lf4 = doc.ArtLayers["date"]
tol4 = lf4.TextItem
tol4.contents = e
lf5 = doc.ArtLayers["contact"]
tol5 = lf5.TextItem
tol5.contents = g
lf6 = doc.ArtLayers["complaint"]
tol6 = lf6.TextItem
varH=" "+h.rstrip("\n")
tol6.contents =varH
lf7 = doc.ArtLayers["allergy"]
tol7 = lf7.TextItem
tol7.contents = i.rstrip("\n")
lf8 = doc.ArtLayers["history"]
tol8 = lf8.TextItem
varJ=" "+j.rstrip("\n")
tol8.contents =varJ
lf9 = doc.ArtLayers["R"]
tol9 = lf9.TextItem
tol9.contents = k.rstrip("\n")
options = win32com.client.Dispatch('Photoshop.ExportOptionsSaveForWeb')
options.Format = 13
options.PNG8 = False
pngfile =ExpDir+f"/{c}-{b}_({e}).png"
doc.Export(ExportIn=pngfile, ExportAs=2, Options=options)
messagebox.showinfo("Prescription Generator", "Prescription has been saved in the desired location successfully!")
There are 3 ways of expressing new line characters:
MacOS uses \r
Linux uses \n
Windows uses \r\n
Python and tkinter use \n but it looks like psApp.Application uses \r instead. That is why the document isn't rendered properly. For more info read the answers to this question.
I'm doing a web scraping data university research project. I started working on a ready GitHub project, but this project does not retrieve all the data.
The project works like this:
Search Google using keywords: example: (accountant 'email me at' Google)
Extract a snippet.
Retrieve data from this snippet.
The issue is:
The snippets extracted are like this: " ... marketing division in 2009. For more information on career opportunities with our company, email me: vicki#productivedentist.com. Neighborhood Smiles, LLC ..."
The snippet does not show all, the "..." hides information like role, location... How can I retrieve all the information with the script?
from googleapiclient.discovery import build #For using Google Custom Search Engine API
import datetime as dt #Importing system date for the naming of the output file.
import sys
from xlwt import Workbook #For working on xls file.
import re #For email search using regex.
if __name__ == '__main__':
# Create an output file name in the format "srch_res_yyyyMMdd_hhmmss.xls in output folder"
now_sfx = dt.datetime.now().strftime('%Y%m%d_%H%M%S')
output_dir = './output/'
output_fname = output_dir + 'srch_res_' + now_sfx + '.xls'
search_term = sys.argv[1]
num_requests = int(sys.argv[2])
my_api_key = "replace_with_you_api_key" #Read readme.md to know how to get you api key.
my_cse_id = "011658049436509675749:gkuaxghjf5u" #Google CSE which searches possible LinkedIn profile according to query.
service = build("customsearch", "v1", developerKey=my_api_key)
wb=Workbook()
sheet1 = wb.add_sheet(search_term[0:15])
wb.save(output_fname)
sheet1.write(0,0,'Name')
sheet1.write(0,1,'Profile Link')
sheet1.write(0,2,'Snippet')
sheet1.write(0,3,'Present Organisation')
sheet1.write(0,4,'Location')
sheet1.write(0,5,'Role')
sheet1.write(0,6,'Email')
sheet1.col(0).width = 256 * 20
sheet1.col(1).width = 256 * 50
sheet1.col(2).width = 256 * 100
sheet1.col(3).width = 256 * 20
sheet1.col(4).width = 256 * 20
sheet1.col(5).width = 256 * 50
sheet1.col(6).width = 256 * 50
wb.save(output_fname)
row = 1 #To insert the data in the next row.
#Function to perform google search.
def google_search(search_term, cse_id, start_val, **kwargs):
res = service.cse().list(q=search_term, cx=cse_id, start=start_val, **kwargs).execute()
return res
for i in range(0, num_requests):
# This is the offset from the beginning to start getting the results from
start_val = 1 + (i * 10)
# Make an HTTP request object
results = google_search(search_term,
my_cse_id,
start_val,
num=10 #num value can be 1 to 10. It will give the no. of results.
)
for profile in range (0, 10):
snippet = results['items'][profile]['snippet']
myList = [item for item in snippet.split('\n')]
newSnippet = ' '.join(myList)
contain = re.search(r'[\w\.-]+#[\w\.-]+', newSnippet)
if contain is not None:
title = results['items'][profile]['title']
link = results['items'][profile]['link']
org = "-NA-"
location = "-NA-"
role = "-NA-"
if 'person' in results['items'][profile]['pagemap']:
if 'org' in results['items'][profile]['pagemap']['person'][0]:
org = results['items'][profile]['pagemap']['person'][0]['org']
if 'location' in results['items'][profile]['pagemap']['person'][0]:
location = results['items'][profile]['pagemap']['person'][0]['location']
if 'role' in results['items'][profile]['pagemap']['person'][0]:
role = results['items'][profile]['pagemap']['person'][0]['role']
print(title[:-23])
sheet1.write(row,0,title[:-23])
sheet1.write(row,1,link)
sheet1.write(row,2,newSnippet)
sheet1.write(row,3,org)
sheet1.write(row,4,location)
sheet1.write(row,5,role)
sheet1.write(row,6,contain[0])
print('Wrote {} search result(s)...'.format(row))
wb.save(output_fname)
row = row + 1
print('Output file "{}" written.'.format(output_fname))
I am trying to create a bar graph in pygal that uses the api for hacker news and charts the most active news based on comments. I posted my code below, but I cannot figure out why my graph keep saying "No data"??? Any suggestions? Thanks!
import requests
import pygal
from pygal.style import LightColorizedStyle as LCS, LightenStyle as LS
from operator import itemgetter
# Make an API call, and store the response.
url = 'https://hacker-news.firebaseio.com/v0/topstories.json'
r = requests.get(url)
print("Status code:", r.status_code)
# Process information about each submission.
submission_ids = r.json()
submission_dicts = []
for submission_id in submission_ids[:30]:
# Make a separate API call for each submission.
url = ('https://hacker-news.firebaseio.com/v0/item/' +
str(submission_id) + '.json')
submission_r = requests.get(url)
print(submission_r.status_code)
response_dict = submission_r.json()
submission_dict = {
'comments': int(response_dict.get('descendants', 0)),
'title': response_dict['title'],
'link': 'http://news.ycombinator.com/item?id=' + str(submission_id),
}
submission_dicts.append(submission_dict)
# Visualization
my_style = LS('#336699', base_style=LCS)
my_config = pygal.Config()
my_config.show_legend = False
my_config.title_font_size = 24
my_config.label_font_size = 14
my_config.major_label_font_size = 18
my_config.show_y_guides = False
my_config.width = 1000
chart = pygal.Bar(my_config, style=my_style)
chart.title = 'Most Active News on Hacker News'
chart.add('', submission_dicts)
chart.render_to_file('hn_submissons_repos.svg')
The values in the array passed to the add function need to be either numbers or dicts that contain the key value (or a mixture of the two). The simplest solution would be to change the keys used when creating submission_dict:
submission_dict = {
'value': int(response_dict.get('descendants', 0)),
'label': response_dict['title'],
'xlink': 'http://news.ycombinator.com/item?id=' + str(submission_id),
}
Notice that link has become xlink, this is one of the optional parameters that are defined in the Value Configuration section of the pygal docs.
I am trying to copy multiple rows from an excel sheet with a Groovy Script, but somehow I am hitting the java.lang.NullPointerException error. The code I am using is the following:
import com.eviware.soapui.support.XmlHolder
import jxl.*
import jxl.write.*
def numofapps = context.expand('${Data_AppNM#NumberOfApplicants}')
def apps2 = ["2","3","4","5","6"]
def myTestCase = context.testCase
def counter,next,previous,size
Workbook workbook1 = Workbook.getWorkbook(new File("C://Path//Multiple records.xls"))
Sheet sheet1 = workbook1.getSheet(0)
size= sheet1.getRows().toInteger()
propTestStep = myTestCase.getTestStepByName("Data")
propTestStep.setPropertyValue("Total", size.toString())
counter = propTestStep.getPropertyValue("Count").toString()
counter = counter.toInteger()
next = (counter > size-2? 0: counter+1)
Cell u1_1 = sheet1.getCell(0,counter)
Cell u2_1 = sheet1.getCell(1,counter)
Cell u3_1 = sheet1.getCell(2,counter)
workbook1.close()
1value1 = u1_1.getContents()
2value1 = u2_1.getContents()
3value1 = u3_1.getContents()
propTestStep.setPropertyValue("A1.1Value", 1value1 )
propTestStep.setPropertyValue("A1.2Value", 2value1 )
propTestStep.setPropertyValue("A1.3Value", 3value1 )
propTestStep.setPropertyValue("Count", next.toString())
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString())
if (apps2.contains(numofapps)){ //setting values for Applicant 2 if requested
counter = propTestStep.getPropertyValue("Count").toString()
counter = counter.toInteger()
next = (counter > size-2? 0: counter+1)
// Extracting the Data from the Excel sheet
Cell u1_2 = sheet1.getCell(0,counter)
Cell u2_2 = sheet1.getCell(1,counter)
Cell u3_2 = sheet1.getCell(2,counter)
workbook1.close()
1value2 = u1_2.getContents()
2value2 = u2_2.getContents()
3value2 = u3_2.getContents()
propTestStep.setPropertyValue("A2.1Value", 1value2 )
propTestStep.setPropertyValue("A2.2Value", 2value2 )
propTestStep.setPropertyValue("A2.3Value", 3value2 )
propTestStep.setPropertyValue("Count", next.toString())
next++ //increase next value
propTestStep.setPropertyValue("Next", next.toString())
}
I am hitting the NullPointerException error on the Cell u1_2 = sheet1.getCell(0,counter) step.
Can you please tell me why I am hitting these and is there any other way that I can use a shorter code?
Thank you :)
The code below creates 3 sub-tasks for each Version selected in SW Version custom field. This is placed on a workflow transition as a post function and works perfectly. However, if the workflow transition is revisited it creates duplicate subtasks for the already selected versions.
Example:
SW Version field has 5 options:
1, 2, 3, 4, 5
if a user selected 1 and 2 and proceeds with the transition, it will create 6 subtasks 3 for each version selected. (All good here)
if the user updates the SW Version field to 1, 2 , 3, and 4 which already has 1 and 2 pre-selected, it will create 12 additional subtasks making the total 18 with 6 duplicates of 1 and 2.
I wanted to put a check on these duplicates, so basic logic is if the subtask already exist go to the next one. Something like for each version selected, check if subtasks already exist and proceed. I tried doing it various ways and failed. Have commented out some codes below to get summary of the subtasks and compare with all existing subtasks summary but it doesn't work.
In addition I tried doing this to no avail.
if(issue.getSubTaskObjects()*.summary.equals(summaryText)){
log.info("Subtask already exists")
return;
Any help would be greatly appreciated !
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueManager
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.util.ImportUtils
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.index.IssueIndexManager
import com.atlassian.jira.issue.link.IssueLinkManager
import com.atlassian.jira.issue.index.IssueIndexingService
import org.apache.log4j.Logger
import org.apache.log4j.Level
log.info("Processing: " + issue.key);
CustomFieldManager customFieldManager = ComponentAccessor.customFieldManager
IssueManager issueManager = ComponentAccessor.getIssueManager();
def cfM119 = customFieldManager.getCustomFieldObjectByName("SW Version")
log.info("cfM119: " + cfM119)
def m119VersionArray = issue.getCustomFieldValue(cfM119) as String[]
def reqAssignee = 'user1'
def swAssignee = 'user2'
def testAssignee = 'user3'
//collecting subtask object
//Collection allsubtasks = issue.getSubTaskObjects()
//for(Issue allsubtask: allsubtasks) {
//def subtaskSummary = allsubtask.getSummary() as String[]
//log.info("Subtask Summary" + subtaskSummary)
//if (subtaskSummary[]){
// log.info("Subtask already exists")}
//else {
m119VersionArray.each{ version ->
createSubTask("", version, "_Approved_REQ", reqAssignee)
createSubTask("", version, "_Approved_SW", swAssignee)
createSubTask("", version, "_Approved_TEST", testAssignee)
}
def createSubTask(String component, version, type, String assignee) {
def Long issueLinkType = new Long (10702)
def Long sequence = new Long (1)
//Issue issue
def summaryText = component + version + " " + type
def issueManager = ComponentAccessor.issueManager
def issueFactory = ComponentAccessor.issueFactory
def subTaskManager = ComponentAccessor.subTaskManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def userManager = ComponentAccessor.userManager
def authenticationContext = ComponentAccessor.jiraAuthenticationContext
if(issue.getSubTaskObjects()*.summary.equals(summaryText)){
log.info("Subtask already exists")
return;
}
// Defining subtask
def newIssue = issueFactory.getIssue()
newIssue.setIssueTypeId("5")
newIssue.setParentId(issue.getId())
newIssue.setProjectObject(issue.getProjectObject())
newIssue.setSummary(summaryText)
newIssue.setAssignee(userManager.getUserByName(assignee))
newIssue.setDescription(issue.getDescription())
log.info("Creating subtask - " + summaryText)
def subTask = issueManager.createIssueObject(authenticationContext.getLoggedInUser(), newIssue)
subTaskManager.createSubTaskIssueLink(issue, subTask, authenticationContext.getLoggedInUser())
issueLinkManager.createIssueLink(issue.getId(), newIssue.getId(), issueLinkType, sequence, authenticationContext.getLoggedInUser())
// reindex
ImportUtils.setIndexIssues(true)
IssueIndexingService issueIndexService =
ComponentAccessor.getComponent(IssueIndexingService.class)
issueIndexService.reIndex(subTask)
ImportUtils.setIndexIssues(false)
}
It's not working just because issue.getSubTaskObjects()*.summary return array and then you try compare this array with string in .equals(summaryText). But you was close and if change this part to issue.getSubTaskObjects()*.summary.contains(summaryText) (mean you search summaryText in each array element) it will be work pretty well.
Also in my opinion next code will be more understandable and clear issue.getSubTaskObjects().find{it.getSummary() == summaryText} (this also will be work inside if statement)