I'm trying to create a table (width = 190px, height = 128px) that is filled with some text and save that as an image. I managed to do that both with matplotlib and by simply generating a HTML table however with both methods I run to the same problem the text gets "compressed" and is blurry. Blurry letters
I would like to generate a pic like this 32x16 pic hand drawn in paint. What would be the best way to achieve this. At the moment I am using python to generate the HTML table and then I am saving it using the html2image library. The table needs to be generated programmatically though. Furthermore I tried to sample only some of the pixels above a threshold but then the text is even worse. The image can be saved as .pgn, .jpg or .bmp Any advice is appreciated! The code below is how I am generating and saving the table ATM.
def printTable(data):
htmlTable = ""
htmlTable += '<table>'
htmlTable += '<tr>'
htmlTable += '<td>%s</td>'% "NAME"
htmlTable += '<td>%s</td>'% "LAST NAME"
htmlTable += '<td>%s</td>'% "PASSWORD"
htmlTable += '<td>%s</td>'% "USERNAME"
htmlTable+= '</tr>'
for element in data.itertuples():
htmlTable += '<tr>'
htmlTable += ('<td>%s</td>'% element.NAME)
htmlTable += ('<td>%s</td>'% element.LAST NAME)
htmlTable += ('<td>%s</td>'% element.PASSWORD)
htmlTable += ('<td>%s</td>'% element.USERNAME)
htmlTable += '</tr>'
htmlTable += '</table>'
return htmlTable
tableString = printTable(df1)
print(tableString)
from html2image import Html2Image
hti = Html2Image(size=(190, 128))
#hti = Html2Image()
html = tableString
css = "\
#font-face {\
font-family: myFirstFont;\
src: url(Dogica Pixel Regular.ttf);\
}\
table, th, td{ \
border:1px solid red; \
border-collapse: collapse; \
background-color: black; \
color:red \
}\
table{ \
widht: 190px;\
font-size: 8px;\
font-family:myFirstFont\
}\
"
hti.screenshot(html_str=html, css_str=css, save_as='htmlTable.png')
Original image
Scaled image
P.S. I really hope hand drawing every pixel on a canvas isn't the only solution xd.
Related
I just started creating an app with Streamlit and have a problem, that the text does not comply with container (column) width:
sequences = []
labels = ["first", "second"]
with st.form(key="fasta_dropdown"):
f_cols = st.columns(2)
for i, col in enumerate(f_cols):
id = col.selectbox(
f"Select {labels[i]} FASTA", fasta_df["ID"], key=i
)
seq = get_sequence_by_id(fasta_df, id)
sequences.append(seq)
with col.expander(label="View sequence"):
st.markdown("""
MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMK
ASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHV
LHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG
"""
)
dropdown_submit = st.form_submit_button("Apply sequences")
How can I fix that? Putting the text into HTML formatting with style="width: 10%" does not change anything.
You can use the CSS property word-wrap:break-word;, which will break words if they are too long for your width.
Code:
st.markdown("""<span style="word-wrap:break-word;">MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMK
ASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHV
LHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG</span>""", unsafe_allow_html=True)
Example:
import streamlit as st
col1, col2 = st.columns(2)
col1.subheader("Col 1")
col1.markdown("""<span style="word-wrap:break-word;">MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMK
ASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHV
LHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG</span>""", unsafe_allow_html=True)
col2.subheader("Col 2")
col2.markdown("""<span style="word-wrap:break-word;">MVLSEGEWQLVLHVWAKVEADVAGHGQDILIRLFKSHPETLEKFDRFKHLKTEAEMK
ASEDLKKHGVTVLTALGAILKKKGHHEAELKPLAQSHATKHKIPIKYLEFISEAIIHV
LHSRHPGNFGADAQGAMNKALELFRKDIAAKYKELGYQG</span>""", unsafe_allow_html=True)
Output:
Trying to get the text inside of the table cells, but have no luck.
I am trying to get the text inside of these cells:
(th and td)
The code works, kind of. It prints out the value as a normal " " (space).
code:
driver.get('https://www.komplett.se/product/1165487/datorutrustning/datorkomponenter/chassibarebone/big-tower/phanteks-eclipse-p500-air')
parent_table = driver.find_element_by_xpath("/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div")
count_of_tables = len(parent_table.find_elements_by_xpath("./table"))
for x in range(count_of_tables):
parent_tr = driver.find_element_by_xpath(f"/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div/table[{x + 1}]/tbody")
count_of_tr = len(parent_tr.find_elements_by_xpath("./tr"))
print(count_of_tr)
for y in range(count_of_tr):
th = driver.find_element_by_xpath(f'/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div/table[{x + 1}]/tbody/tr[{y+1}]/th')
td = driver.find_element_by_xpath(f'/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div/table[{x + 1}]/tbody/tr[{y + 1}]/td')
print(th.text)
print(td.text)
for y in range(count_of_tr):
th = driver.find_element_by_xpath(
f'/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div/table[{x + 1}]/tbody/tr[{y+1}]/th')
td = driver.find_element_by_xpath(
f'/html/body/div[2]/main/div[2]/div[2]/div[3]/div/div[2]/div/section[2]/div/div/div/table[{x + 1}]/tbody/tr[{y + 1}]/td')
print(th.get_attribute("textContent"))
print(td.get_attribute("textContent"))
use get attribute text content as , text will retrieve text visible in view port only
I am working on a python project where I have data stored in QTableWidget. I have to export this data into excel sheet and PDF. I have been able to export data to excel sheet using below code. But unable to understand how can I convert it to PDF.
filename, _ = QFileDialog.getSaveFileName(self, 'Save File', '', ".xls(*.xls)")
wbk = xlwt.Workbook()
sheet = wbk.add_sheet("sheet", cell_overwrite_ok=True)
style = xlwt.XFStyle()
font = xlwt.Font()
font.bold = True
style.font = font
model = self.home_ui.reports_table.model()
for c in range(model.columnCount()):
text = model.headerData(c, QtCore.Qt.Horizontal)
first_col = sheet.col(c+1)
l = len(text)
first_col.width = (256 * l) + 1000
sheet.write(0, c + 1, text, style=style)
for r in range(model.rowCount()):
text = model.headerData(r, QtCore.Qt.Vertical)
sheet.write(r + 1, 0, text, style=style)
for c in range(model.columnCount()):
for r in range(model.rowCount()):
text = model.data(model.index(r, c))
sheet.write(r + 1, c + 1, text)
wbk.save(filename)
Above code is working fine and saving data to excel.
I have looked into other questions with same topic but all of them are in c++. I am looking for python equivalent.
Can anyone give me some good suggestion on how to convert data to PDF. Please help. Thanks
When you review an answer you should not only see the code but the solution itself, that is, the logic that is in the background. In this particular case the solution is to create an HTML that shows the table content, and use QTextDocument with QPrinter to print the HTML to PDF.
Considering the above, it is not necessary to do the translation since it is enough to implement it from scratch since the logic is clear.
from PyQt5 import QtCore, QtGui, QtWidgets, QtPrintSupport
app = QtWidgets.QApplication([])
w = QtWidgets.QTableWidget(10, 10)
for i in range(10):
for j in range(10):
it = QtWidgets.QTableWidgetItem("{}-{}".format(i, j))
w.setItem(i, j, it)
filename = "table.pdf"
model = w.model()
printer = QtPrintSupport.QPrinter(QtPrintSupport.QPrinter.PrinterResolution)
printer.setOutputFormat(QtPrintSupport.QPrinter.PdfFormat)
printer.setPaperSize(QtPrintSupport.QPrinter.A4)
printer.setOrientation(QtPrintSupport.QPrinter.Landscape)
printer.setOutputFileName(filename)
doc = QtGui.QTextDocument()
html = """<html>
<head>
<style>
table, th, td {
border: 1px solid black;
border-collapse: collapse;
}
</style>
</head>"""
html += "<table><thead>"
html += "<tr>"
for c in range(model.columnCount()):
html += "<th>{}</th>".format(model.headerData(c, QtCore.Qt.Horizontal))
html += "</tr></thead>"
html += "<tbody>"
for r in range(model.rowCount()):
html += "<tr>"
for c in range(model.columnCount()):
html += "<td>{}</td>".format(model.index(r, c).data() or "")
html += "</tr>"
html += "</tbody></table>"
doc.setHtml(html)
doc.setPageSize(QtCore.QSizeF(printer.pageRect().size()))
doc.print_(printer)
I am having problems with writing to my HTML file.
I want to be able to make my code place what I have written in HTML, but my code will only do it when I do not have any While/If statements in this definition. If I do have Whiles/Ifs, my HTML file will simply just become blank. I have no idea why this happens, and I can't seem to find a workaround.
Is there any way to use Whiles/Ifs without making my code delete everything in my file, and instead make it write what I want to in there?
def invoice_creator_window():
global total_cost, total_cost_list, list_of_items, invoice_created
invoice_created = Toplevel()
invoice_created.focus_set()
invoice_created.resizable(width = True, height = False)
invoice_created.title("Invoice Created")
invoice_created.geometry("300x300")
invoice_created.geometry("+400+400")
invoice_created.configure(bg = "limegreen")
currentDisplay = 10
print(total_cost, total_cost_list, list_of_items)
done = Label(invoice_created, text = "Items have been purchased. Invoice has been created. Please check this program's file location.")
invoice_created = Button(invoice_created, text = "Done", bg = "white", command = close_window)
#
done.grid(row = 1, column = 1, padx = 7.5, pady = space_between)
invoice_created.grid(row = 2, column = 1, padx = 7.5, pady = space_between)
# This section is for the invoice creation with HTML.
html_formatting_start = """<!DOCTYPE html>
<html>
<head>
<title>Games R Us - Invoice</title>
</head>
<body>
<style>
body {background-color: #F7D358;}
h1 {color: #775A03;}
p {color: ; border: 1px solid #775A03; padding: 15px; width: 650px}
</style>
<center>
<h1>Games R Us - Invoice Document</h1>
"""
counter = 0
while len(list_of_items) > 0:
global html_formatting_mid
print(counter)
html_formatting_mid = ("""
<h3>
<p>
<img src="https://steamcdn-a.akamaihd.net/steam/apps/211420/header.jpg?t=1483694369"</img>
<br>""" + str(list_of_items[counter]) + """<br>
<i>$""" + str(total_cost_list[counter]) + """ AUD</i>
</p>
</h3>
""")
if counter >= len(list_of_items) - 1:
return
else:
counter += 1
html_formatting_end = """
<h2>In Total: $""" + str(total_cost) +""" AUD</h2>
<br>
<b>Information Grabbed from These Links: </b>
Steam's New Releases [LIVE] -
Steam's Top Sellers [LIVE] -
Umart's Headphones [PRE-DOWNLOADED] -
Umart's Microphones [PRE-DOWNLOADED]
</center>
</body>
</html>"""
invoice_creation = open(invoice_file, "w")
invoice_creation.write(html_formatting_start)
invoice_creation.write(html_formatting_mid)
invoice_creation.write(html_formatting_end)
invoice_creation.close()
#############################################################################
button_buy = Button(welcome_window, text = "Buy", fg = "white", bg = "goldenrod", font = gui_font_10,
command = invoice_creator_window)
Note: "total_cost_list" and "list_of_items" are all lists. "total_cost" is a value. Do not worry too much about the context of these, but I wanted to clarify in case they might be affecting anything.
Here is a fixed version of your code in as simple a container as possible.
from tkinter import *
import webbrowser
root = Tk ()
space_between, invoice_file = 5, "Invoice.html"
total_cost, total_cost_list, list_of_items = 10, [1, 9], ["Something", "Something 2"]
def close_window (): root.destroy ()
def invoice_creator_window():
global total_cost, total_cost_list, list_of_items, invoice_created
invoice_created = Toplevel()
invoice_created.focus_set()
invoice_created.resizable(width = True, height = False)
invoice_created.title("Invoice Created")
invoice_created.geometry("300x300")
invoice_created.geometry("+400+400")
invoice_created.configure(bg = "limegreen")
currentDisplay = 10
print(total_cost, total_cost_list, list_of_items)
done = Label(invoice_created, text = "Items have been purchased. Invoice has been created.")
invoice_created = Button(invoice_created, text = "Done", bg = "white", command = close_window)
#
done.grid(row = 1, column = 1, padx = 7.5, pady = space_between)
invoice_created.grid(row = 2, column = 1, padx = 7.5, pady = space_between)
# This section is for the invoice creation with HTML.
html_formatting_start = """<!DOCTYPE html>
<html>
<head>
<title>Games R Us - Invoice</title>
</head>
<body>
<style>
body {background-color: #F7D358;}
h1 {color: #775A03;}
p {color: ; border: 1px solid #775A03; padding: 15px; width: 650px}
</style>
<center>
<h1>Games R Us - Invoice Document</h1>
"""
counter = 0
html_formatting_mid = ""
while len(list_of_items) > 0:
print(counter)
html_formatting_mid += """
<h3>
<p>
<img src="https://steamcdn-a.akamaihd.net/steam/apps/211420/header.jpg?t=1483694369"</img>
<br>""" + str(list_of_items[counter]) + """<br>
<i>$""" + str(total_cost_list[counter]) + """ AUD</i>
</p>
</h3>
"""
if counter >= len(list_of_items) - 1:
break
else:
counter += 1
html_formatting_end = """
<h2>In Total: $""" + str(total_cost) +""" AUD</h2>
<br>
<b>Information Grabbed from These Links: </b>
Steam's New Releases [LIVE] -
Steam's Top Sellers [LIVE] -
Umart's Headphones [PRE-DOWNLOADED] -
Umart's Microphones [PRE-DOWNLOADED]
</center>
</body>
</html>"""
invoice_creation = open(invoice_file, "w")
invoice_creation.write (html_formatting_start + html_formatting_mid + html_formatting_end)
invoice_creation.close ()
webbrowser.open (invoice_file)
#############################################################################
button_buy = Button(root, text = "Buy", fg = "white", bg = "goldenrod",
command = invoice_creator_window).pack ()
root.mainloop ()
I found a solution.
def invoice_creator_window():
global total_cost, total_cost_list, list_of_items, invoice_created
invoice_created = Toplevel()
invoice_created.focus_set()
invoice_created.resizable(width = True, height = False)
invoice_created.title("Invoice Created")
invoice_created.geometry("300x300")
invoice_created.geometry("+400+400")
invoice_created.configure(bg = "limegreen")
currentDisplay = 10
print(total_cost, total_cost_list, list_of_items)
done = Label(invoice_created, text = "Items have been purchased. Invoice has been created. Please check this program's file location.")
invoice_created = Button(invoice_created, text = "Done", bg = "white", command = close_window)
#
done.grid(row = 1, column = 1, padx = 7.5, pady = space_between)
invoice_created.grid(row = 2, column = 1, padx = 7.5, pady = space_between)
# This section is for the invoice creation with HTML.
html_formatting_start = """<!DOCTYPE html>
<html>
<head>
<title>Games R Us - Invoice</title>
</head>
<body>
<style>
body {background-color: #F7D358;}
h1 {color: #775A03;}
p {color: ; border: 1px solid #775A03; padding: 15px; width: 650px}
</style>
<center>
<h1>Games R Us - Invoice Document</h1>
"""
counter = 0
html_formatting_mid = ""
for items in list_of_items:
print(counter)
html_formatting_mid += ("""
<h3>
<p>
<img src="https://steamcdn-a.akamaihd.net/steam/apps/211420/header.jpg?t=1483694369"</img>
<br>""" + str(list_of_items[counter]) + """<br>
<i>$""" + str(total_cost_list[counter]) + """ AUD</i>
</p>
</h3>
""")
counter += 1
html_formatting_end = """
<h2>In Total: $""" + str(total_cost) +""" AUD</h2>
<br>
<b>Information Grabbed from These Links: </b>
Steam's New Releases [LIVE] -
Steam's Top Sellers [LIVE] -
Umart's Headphones [PRE-DOWNLOADED] -
Umart's Microphones [PRE-DOWNLOADED]
</center>
</body>
</html>"""
invoice_creation = open(invoice_file, "w")
invoice_creation.write(html_formatting_start)
invoice_creation.write(html_formatting_mid)
invoice_creation.write(html_formatting_end)
invoice_creation.close()
#############################################################################
button_buy = Button(welcome_window, text = "Buy", fg = "white", bg = "goldenrod", font = gui_font_10,
command = invoice_creator_window)
I went back to my older use of a for loop and tried using that. Except this time, I added html_formatting_mid += (""" to it, and then before the for loop, just added html_formatting_mid = "", like Minion Jim showed.
It works fully now.
A short answer would be, you could just write in append mode. open (filename, 'a') instead of open (filename, 'w'). This will add on to whatever is already in the file, so you may want to truncate it first.
trying to create several web pages that contains tables from the read csv file and I tried to define a function to create html web pages rather than writing the same codes many times.
read my csv file:
infile = open("new.csv", "r")
data = []
for line in infile:
cols = line.split(",")
Oposition = cols[0]
Winner = cols[1]
Margin = cols[2]
Ground = cols[3]
Year = cols[4]
pair = (Oposition, Winner, Margin, Ground, Year)
data.append(pair)
infile.close()
so far my codes are:
page = """<!DOCTYPE html>
<html>
<head>
<title>abc</title>
<style>
h1 {
text-align: center;
}
body {
background-image: url("2014.png");
background-repeat: no-repeat;
background-position: right top;
background-attachment: fixed;
}
</style>
</head>
<body>
<h1>{{heading}}</h1>
{{paragraph}}
<p>Back to main page</p>
<table border="1"><tr><th>Oposition</th><th>Winner</th><th>Margin</th><th>Ground</th><th>Year</th></tr>
"""
out1=page.format(heading = "2012 Stats", paragraph = "<p>aaaaaaa</p>")
out2 = page.format(heading = "2013 Stats", paragraph = "<p>bbbbb</P>")
out3 = page.format(heading = "2014 Stats", paragraph = "<p>cccc</P>")
out4 = page.format(heading = "2015 Stats", paragraph = "<p>ddddCSK</p>")
def write_html_file(filename, body):
out = open(filename, "w")
out.write(body)
write_html_file("2012.html",out1)
write_html_file("2013.html",out2)
write_html_file("2014.html",out3)
write_html_file("2015.html",out4)
for r in data:
if ''.join(r[4].split()) == "2012":
Oposition = r[0]
Winner = r[1]
Margin = r[2]
Ground=r[3]
Year = r[4]
out1.write("<tr> <td>" + Oposition+ '</td><td> '+ Winner+'</td><td> '+Margin+'</td><td> '+Ground+' </td><td>'+ Year+ " </td></tr>")
elif ''.join(r[4].split()) == "2013":
Oposition = r[0]
Winner = r[1]
Margin = r[2]
Ground=r[3]
Year = r[4]
out2.write("<tr> <td>" + Oposition+ '</td><td> '+ Winner+'</td><td> '+Margin+'</td><td> '+Ground+' </td><td>'+ Year+ " </td></tr>")
elif ''.join(r[4].split()) == "2014":
Oposition = r[0]
Winner = r[1]
Margin = r[2]
Ground=r[3]
Year = r[4]
out3.write("<tr> <td>" + Oposition+ '</td><td> '+ Winner+'</td><td> '+Margin+'</td><td> '+Ground+' </td><td>'+ Year+ " </td></tr>")
elif ''.join(r[4].split()) == "2015":
Oposition = r[0]
Winner = r[1]
Margin = r[2]
Ground=r[3]
Year = r[4]
out4.write("<tr> <td>" + Oposition+ '</td><td> '+ Winner+'</td><td> '+Margin+'</td><td> '+Ground+' </td><td>'+ Year+ " </td></tr>")
def output(a):
a.write("</table> </body>\n")
a.write("</html>\n")
a.close()
output(out1)
output(out2)
output(out3)
output(out4)
im trying to make tables according to years 2012, 2013, 2014, 2015 and make html pages that contains each of them. just cant figure out.
Any help or other option? Much appreciated
I get an error message saying:
---> 25 page1 = page.format(heading = "2012 Stats", paragraph = "<p>aaaa</p>")
KeyError: '\n text-align'
Short Answer
Python's built-in string format syntax is a variable enclosed by single paramthesis. That's why '\n text-align' is regarded as a key whereas it was intended to be a css style.
Solution
You can go ahead to escape your css snippets but I would not recommend it, because the html text will not be readable and will be difficult to maintain.
Hence, please use a template engine to help. There are many template engines: Jinja2, Mako.. etc. Since I am more familiar with the first one, let me show you how to get page1 working::
from jinja2 import Environment
env = Environment()
page_template = env.from_string(page)
page1 = page_template(heading="2012 Stats", paragraph="<p>aaaaaaa</p>")
And you will need to install jinja2:
$ pip install jinja2
Alternative solution
You can use my library pyexcel and pyexcel-text to get a html table rendered for you. The sample code is:
import pyexcel as p
sheet = p.get_sheet(file_name='new.csv')
sheet.colnames = ['Oposition', 'Winner', 'Margin', 'Ground', 'Year']
sheet.name = "2012 Stats"
print(sheet.html)
To run above code, you need to install these two additional packages:
$ pip install pyexcel pyexcel-text