multiple value from mysql to reportlab - python

i have an issue that i can't show my second record in mysql table. The report just showing 1 record in a row and the second one isn't show on pdf file. i'm using reportlab for report generator on python 2.7
this is my code that i can' fix yet :
def nilaisql():
rpt = raw_input("input NPM : ")
sql = "select nama, tanggal, jamMasuk from t_"+rpt
curs.execute(sql)
result = curs.fetchall()
for row in result:
c = canvas.Canvas("Sampelone.pdf")
c.drawString(250, 700, str(row[0]))
c.save()
os.system("Sampelone.pdf")
this is my record on mysql. I want to show the second row record but the pdf just showing the first row record
it should showing the second row record
and this is the result on my pdf file
i'm getiing stuck in here and if you know something i'm really grateful that you can share the solution in here

for row in result:
c = canvas.Canvas("Sampelone.pdf")
c.drawString(250, 700, str(row[0]))
c.save()
what your code snippet is doing is, creating a new file and writing the content of your variable row into the pdf file and c.save saves it. In the next iteration, this same file is recreated which is blank and the original file is overwritten by this blank file and the content of row is printed that is why you will always see only first row record in it.
This should work fine. Increment or Decrement the value of y according to your use and document height.
c = canvas.Canvas("Sampelone.pdf") #creates a pdf
for row in result:
c.drawString(250, y, str(row[0])) #writes data at given co-ordinates
c.save() #saves the pdf
This way you can see all row records in the pdf.
But this practice is not considered good, you should always put your data in flowable like this. .
from reportlab.lib import styles
from reportlab.platypus import SimpleDocTemplate, Paragraph
def nilaisql():
pdfname = 'mydoc.pdf'
doc = SimpleDocTemplate(
pdfname
)
style = styles["Normal"]
story = []
rpt = raw_input("input NPM : ")
sql = "select nama, tanggal, jamMasuk from t_" + rpt
curs.execute(sql)
result = curs.fetchall()
for row in result:
story.append(Paragraph(row, style))
doc.build(
story
)
os.system("Sampelone.pdf")
Read more about flowables in reportlab-userguide

Related

Modify Named Table in Excel File with Python openpyxl

I want to add columns to an existing table in an excel file.
Therefore I wan't to use python and the openpyxl library.
Right now I use a class when it is initialising, it is connecting to the file.
Afterwards I call the check_for_column function and when the column is not existing it should create it. And in the end of the script I save the file.
import os
from openpyxl import load_workbook
from openpyxl.worksheet.table import Table, TableColumn, range_boundaries
from openpyxl.utils.cell import get_column_letter
class ExcelHandler:
_wb_name = None
_table = None
_wb = None
def __init__(self):
self._wb_name = os.getenv('EXCEL_FULLPATH')
self._wb = load_workbook(filename=self._wb_name, keep_vba=True)
sheet = self._wb['DataInbox']
self._table = sheet.tables['WebPageForms']
return
def check_for_column(self, column_name):
if not column_name in self._table.column_names:
lst_ids = [my_object.id for my_object in self._table.tableColumns]
new_id = lst_ids[-1]+1
# change range of table
min_col, min_row, max_col, max_row = range_boundaries(
self._table.ref)
max_col += 1
mx = get_column_letter(max_col)
mn = get_column_letter(min_col)
self._table.ref = '{}{}:{}{}'.format(mn, min_row, mx, max_row)
# add column to table
tc = TableColumn(id=new_id, name=column_name)
self._table.tableColumns.append(tc)
return
def save_wb(self):
self._wb.save(self._wb_name)
return
The code runs fine as shown. Although when I then try to open the file with excel it gives me an alert saying:
We found a problem with some content in ’file.xlsm’. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.
This is the repair result of excel when I press yes
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"><logFileName>Repair Result to file.xml</logFileName><summary>Errors were detected in file ’*path*/file.xlsm’</summary><repairedRecords summary="Following is a list of repairs:"><repairedRecord>Repaired Records: Table from /xl/tables/table1.xml part (Table)</repairedRecord></repairedRecords></recoveryLog>
I would highly appreciate If anyone could help me
Ok, I found the problem why the excel file is corrupt, my bad.
when I create the column in the table, I also have to write the name in the respective cell:
def check_for_column(self, column_name):
***
# write name in cell of new column header
self._ws.cell(row=min_row, column=max_col).value = column_name
***
return
If I add this to the code, my table is modified correctly

I am not able to see table borders when I create a prettytable

I am writing this simple code like so
import prettytable
# open csv file
a = open("dash", 'r')
# read the csv file
a = a.readlines()
# headers for table
t = prettytable.PrettyTable(field_names=["Test", "Status"], title="Test Report",
header_style="title", header=True,
hrules=prettytable.ALL, vrules=prettytable.ALL)
# Adding the data
for i in range(len(a)):
row = a[i].split(',')
t.add_row([row[0], row[1]])
t.add_row(["",""])
code = t.get_html_string()
html_file = open('Table.html', 'w')
html_file = html_file.write(code)
But I get output like this
Test Report
Test Status
test1 pass
test2 fail
Why am I not able to see the table borders?
Hope this isn't too late! Just ran in to this issue myself and in my searching found this question and found the solution here (example #3).
In this case, where you are have the command
code = t.get_html_string()
Change it to
code = t.get_html_string(attributes={'border': 1, 'style': 'border-width: 1px; border-collapse: collapse;'})
Once that is changed, the borders should be added in the HTML.

Python Refresh GUI to create another output

I am very new to Python. I am trying to create an app that printing a number from a Smartsheet sheet then delete it. The problem is I only can print it once, once I click "Create" button again, it gives error message. I believe when I click "Create" button again, it returns the deleted number from the sheet. Thank you!
{"response": {"statusCode": 404, "reason": "Not Found", "content": {"detail": {"ids": [3462338204985220], "type": "row"}, "errorCode": 1006, "message": "Not Found", "refId": "hcuqkioxqz46"}}}
Here is the sheet that stores a series of number:
Here is my code:
#Smartsheet client access token
smartsheet_client = smartsheet.Smartsheet('access token')
#Order Dashboard sheet ID
MySheet=smartsheet_client.Sheets.get_sheet(sheet_id)
def conceptnum():
n=1
for Myrow in MySheet.rows:
while n==1:
for Mycell in Myrow.cells:
row_ids=Myrow.id
label1['text']=int(Mycell.value)
label2['text']="Your concept number is created"
smartsheet_client.Sheets.delete_rows(
sheet_id, # sheet_id
row_ids) # row_ids
n=n-1
Height=100
Width=200
root=tk.Tk()
canvas=tk.Canvas(root, height=Height, width=Width)
canvas.pack()
frame=tk.Frame(root, bg="grey")
frame.place(relx=0.05, rely=0.3, relwidth=0.9, relheight=0.4)
button=tk.Button(root, text="Create",command=conceptnum)
button.pack(side='bottom')
label1=tk.Label(frame,font=15)
label1.place(relx=0.1, rely=0.1,relwidth=0.8, relheight=0.8)
label2=tk.Label(root)
label2.place(relwidth=1,relheight=0.2)
root.mainloop()
As currently written, your conceptnum() function is doing this:
for each row in the sheet ->
for each cell in the current row ->
...
delete the current row
So, if your sheet contains more than one column, your script will:
get the first row of the sheet
get the value of the first cell of the row being processed
delete the row from the sheet
get the value of the second cell of the row being processed
delete the row from the sheet -> this delete row request (and the subsequent request for each additional column/cell in the row being processed) will return the "Not Found" error -- because that row no longer exists in the sheet -- you deleted it after reading the first cell value.
Assuming that your objective is to read the value in the first cell of the first row of the sheet, and then delete that row from the sheet, here's a function that will do so -- please note that I've changed the function name and variable names to follow Python style convention (lowercase with underscores):
def concept_num():
# get sheet
my_sheet = smartsheet_client.Sheets.get_sheet(sheet_id)
# initialize row_id
row_id = None
for row in my_sheet.rows:
# get the ID of the current (first) row
row_id = row.id
# get the Cell object for the first cell of the current (first) row
cell = row.cells[0]
# set labels
label1['text'] = int(cell.value)
label2['text'] = 'Your concept number is created'
# exit the 'for' loop (so that only the first row is processed)
break
# delete the row that was just processed
if row_id != None:
smartsheet_client.Sheets.delete_rows(sheet_id, row_id)
else:
label1['text'] = 'n/a'
label2['text'] = 'Concept number not found.'
EDIT 4/13/2020:
You need to fetch the sheet each time the concept_num function runs -- so that my_sheet reflects the current contents of the sheet (i.e., no longer contains rows that were deleted when the function ran previously). I've updated the code snippet above accordingly (i.e., added the get sheet call at the top of the concept_num function). I've also added code at the end of the snippet (using an else) to update labels accordingly if the sheet contains no more numbers when the Create button is clicked.

How to Iterate through data present in the spread sheet in selenium/data

I am automating a web page where the data is entered in web pages from spread sheet like name ,date of birth.i am able to run if there a single record in a spread sheet.the issue is i don't how to iterate through the spread sheet if i have n number data in a spread sheet .
Below,as of now,i able to fetch the 1 record.i would like to fetch both record 1&2
Example as in spread sheet:
Record Name DOB
1 TEST1 05/06/2010
2 TEST2 06/05/2010
Please find the code i have tried so far
driver = webdriver.Chrome('path')
driver.fullscreen_window();
driver.get('url');
time.sleep(5);
Workbook=xlrd.open_workbook("excelpath")
Customerdetails = Workbook.sheet_by_index(0);
Storagezipcode = Customerdetails.cell(1,0);
text_area=driver.find_element_by_xpath('(//*[#id="QuoteDetails/PostalCode"])[2]');
text_area.send_keys(Storagezipcode.value);
Nextbutton=driver.find_element_by_xpath('//span[contains(text(),"Next")]');
Nextbutton.click()
time.sleep(10)
#carlink page
CarLink=driver.find_element_by_xpath('//span[#class="link"]');
CarLink.click();
time.sleep(30)
#ModelYear page
yeardetail=Customerdetails.cell(1,14);
Yearlink = driver.find_element_by_xpath("//span[normalize-space(.)='{}']".format(yeardetail.value));
Yearlink.click();
time.sleep(10)
#Company name
SubModel=Customerdetails.cell(1,15);
SubModellink=driver.find_element_by_xpath("//span[normalize-space(.)='{}']".format(SubModel.value));
SubModellink.click();
time.sleep(10)
#Company model
Bodymodel=Customerdetails.cell(1,16);
Bodylink=driver.find_element_by_xpath("//span[normalize-space(.)='{}']".format(Bodymodel.value));
Bodylink.click();
time.sleep(10);
Use the row count to get all the rows and then iterate and use column index.
import xlrd
Workbook=xlrd.open_workbook("excelpath")
Customerdetails = Workbook.sheet_by_index(0)
for i in range(1,Customerdetails.nrows):
Record=Customerdetails.cell(i,0)
print(Record.value)
Name= Customerdetails.cell(i,1)
print(Name.value)
DOB = Customerdetails.cell(i, 2)
print(DOB.value)

Get info from a table on a website where XPATH varies on each site, Python

If you take this website as an example:
http://gbgfotboll.se/information/?scr=table&ftid=51168
I am using this code to get information from the second table:
for url in urlList:
request = net.Request(url)
response = net.urlopen(request)
data = response.read()
dom = lxml.html.parse(BytesIO(data))
#all table rows
xpatheval = etree.XPathDocumentEvaluator(dom)
rows = xpatheval('//div[#id="content-primary"]/table[2]/tbody/tr')
divName = xpatheval('//*[#id="content-primary"]/h1//text()')[0]
trash, divisionName = divName.rsplit("- ")
dict[divisionName] = {}
for id,row in enumerate(rows):
columns = row.findall("td")
teamName = columns[0].find("a").text, # Lag
print teamName
teamName
playedGames = columns[1].text, # S
wins = columns[2].text,
draw = columns[3].text,
lost = columns[4].text,
dif = columns[6].text, # GM-IM
points = columns[7].text, # P - last column
dict[divisionName].update({id :{"teamName":columns[0].find("a").text, "playedGames":playedGames, "wins":wins, "draw":draw, "lost":lost, "dif":dif, "points":points }})
For that website the rows has table[2]
For this website:
http://gbgfotboll.se/serier/?scr=table&ftid=57108
the rows would need to look like this:
rowss = '//div[#id="content-primary"]/table[1]/tbody/tr'[0]
So what I am asking for if there is a way to get the information I need regardless what table index the table will be at?
One way to do it would be to select by its class attribute (all 3 classes are required):
xpatheval('//div[#id="content-primary"]/table[#class="clCommonGrid clTblStandings clTblWithFullToggle"]/tbody/tr'
An alternative would be to select a child element in that table that you know is only present in that specific type of table. For example, the GM-IM header could be quite specific to that type of table, so I navigate to it and then work my way up the tree to end up with the same rows as you:
xpatheval('//div[#id="content-primary"]//tr[th="GM-IM"]/../../tbody/tr')

Categories