How to export arabic characters to pdf in xhtml2pdf? - python

I want to export arabic characters to pdf using xhtml2pdf, cause I'm using it in my django app.
I know that they made an update saying that they fixed it, but it didn't work with me, I used a custom font but still not working.
So please anyone knows the right encryption for this or anyway around it, help me.
invoice.html :
{% load static %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<head>
<title>{{title}}</title>
<style type="text/css">
#font-face {
font-family: Amiri, "Amiri Font";
src: url("{% static 'font/Amiri-Italic.ttf'%}");
}
body {
font-weight: 200;
font-size: 14px;
}
</style>
</head>
<body><pdf:language name="arabic"/>
<div class='wrapper'>
<div class='header'>
<p class='title'>Invoice # {{ invoice_ID }} </p>
</div>
<div>
<div class='details'>
<pdf:language name="arabic"/>
<p> تجربة</p>
customername : {{customer_name}} <br><hr>
<hr class='hrItem' />
</div>
</div>
</body>
</html>
utils.py :
from io import BytesIO
from django.http import HttpResponse
from django.template.loader import get_template
from xhtml2pdf import pisa
def render_to_pdf(template_src, context_dict={}):
template = get_template(template_src)
html = template.render(context_dict)
result = BytesIO()
pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result)
if not pdf.err:
return HttpResponse(result.getvalue(), content_type='application/pdf')
return None
views.py :
from django.shortcuts import render, redirect, HttpResponse
import pandas as pd
from .models import SaleInvoice, TransferWays, User, InstallingCities
from siteManagment.models import MarketersManagment, WareHouses
from .utils import render_to_pdf
from django.core.validators import ValidationError
def renderPDF(request):
if request.GET:
invoice_ID = request.GET.get('invoice_ID')
if invoice_ID:
result = SaleInvoice.objects.all().filter(invoice_ID=invoice_ID).values()
df = pd.DataFrame(result)
#theUser = User.objects.all().filter(id=(df['User_id'])).values('username')
#df['total'].values
data = {
"title" : ' الفاتورة رقم {}'.format(invoice_ID),
"invoice_ID" : invoice_ID,
"customer_name" : df['customer_name'],
}
pdf = render_to_pdf('invoice.html', data)
return HttpResponse(pdf, content_type='application/pdf')
else:
raise ValidationError
else:
return redirect('admin/')

I solved it, the docs have nothing wrong actually, the problem was in the static.. because when you use {% static 'whatever' %} it's going to search the static files but for some reason it didn't work I think the problem is from django itself, maybe you can't summon static from a pdf file. anywho this is my new invoice.html ( I've put the whole path to the font ):
{% load static %}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<head>
<title>{{title}}</title>
<style type="text/css">
.header {
font-size: 20px;
font-weight: 100;
text-align: center;
color: #007cae;
}
.title {
font-size: 22px;
font-weight: 100;
/* text-align: right;*/
padding: 10px 20px 0px 20px;
}
.title span {
color: #007cae;
}
.details {
padding: 10px 20px 0px 20px;
text-align: right !important;
/*margin-left: 40%;*/
}
.hrItem {
border: none;
height: 1px;
/* Set the hr color */
color: #333;
/* old IE */
background-color: #fff;
/* Modern Browsers */
}
#font-face {font-family: RTLFont; src: url('C:\\Users\\BigBoy\\Desktop\\MyProjects\\ToysSite\\static\\font\\Amiri-Italic.ttf')} // Here
body {
font-weight: 200;
font-size: 14px;
font-family: RTLFont;
}
/* #page {
background-image: url('C:\Users\BigBoy\Desktop\MyProjects\ToysSite\static\background.png');
} */
</style>
</head>
<body>
<div class='wrapper'>
<div class='header'>
</div>
<div>
<div class='details'>
<pdf:language name="arabic"/>
اسم العميل : {{customer_name}} <br><hr>
<hr class='hrItem' />
</div>
</div>
</div>
</body>
</html>

Related

Background won't run with flask [duplicate]

This question already has answers here:
How to serve static files in Flask
(24 answers)
Closed 1 year ago.
I have this application and I made an animation background and when I open the HTML in chrome so it works well but then when I run it with flask It doesn't add the background and just ignores it
It's probably something that I missed but I still can't understand why it doesn't load the background
HTML - 1:
<!doctype html>
<html>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
<title>Covid-19</title>
</head>
<body>
<section>
<h1>Animated something</h1>
</section>
{% block content %}
{% endblock content %}
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>
CSS:
#import "https://fonts.googleapis.com/css?family=Lato:100";
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html{
font-size: 10px;
font-family: "Latop", Arial, sans-serif;
}
section{
width: 100%;
height: 100vh;
color: #fff;
background: linear-gradient(-45deg, #EE7752, #E73C7E, #23A6D5, #23D5AB);
background-size: 400% 400%;
position: relative;
animation: change 10s ease-in-out infinite;
}
h1{
font-size: 5rem;
text-transform: uppercase;
letter-spacing: 2px;
border: 3px solid #fff;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 5rem 10rem;
}
#keyframes change{
0%{
background-position: 0 50%;
}
50%{
background-position: 100% 50%;
}
100%{
background-position: 0 50%;
}
}
Python:
from flask import Flask, render_template, request
def create_app():
app = Flask(__name__)
#app.route('/', methods=['POST', 'GET'])
def home():
return render_template("base.html")
return app
It's due to the server being unable to locate the style.css file. To fix this, make sure your static files are located inside a folder named 'static' next to your flask application python file. something like this:
/app
- app.py
/templates
- base.html
/static
- style.css
And to easily link the files in the templates using:
<link rel="stylesheet" href="{{ url_for('static',filename='style.css') }}">
Check Flask's docs for more details
Good luck :)

css display: block is not working on flask?

I'm starting learning flask and I'm planning on makin a sorting algorithm visualizer using flask and I'm tryin to represent the elements of the array as bars (the height of the bars is = to the value of each element in the array). I'm thinking to use the display: block but it does not appear on the page. Pls help me or suggest anything if this is possible
html file:
<!DOCTYPE html>
<html>
<head>
<title>Sample</title>
<link rel="stylesheet" href="{{ url_for('static', filename='design.css') }}">
</head>
<body>
<div class="bar">
<p>test</p>
</div>
</body>
</html>
css file:
.bar{
display: inline-block;
height: 120px;
width: 5px;
background-color: red;
color: white;
}
this what only shows on my page. other css property works well this display: bar was the only problem
Normally this is an issue with browser caching. If you did not use a file and added it directly to <head> it should work
<head>
<style>
.bar{
display: inline-block; /*You want block or inline-block?*/
height: 120px;
width: 5px;
background-color: red;
color: white;
}
</style>
</head>
If you really want to use the css file, use versioning in the url:
/static/design.css/?v=1 next time /static/design.css/?v=2
But it becomes tedious. You can add a random variable like this:
import uuid
v = str(uuid.uuid4())
# url_for('static', filename='design.css', v=v)
Please clarify your answer using a screenshot of what is happening now

Save configuration of pivottablejs in Jupyter notebook

I am using google Colab (Jupyter python notebook on a server) to run the pivot table.
This code:
pivot_ui(d1,outfile_path='pivottablejs.html')
HTML('pivottablejs.html')
Results in this blank pivot:
Which I can manipulate to get this desired chart:
But when I refresh the page it all goes back to the blank pivot. What I would like is to store the config of the desired chart so that I can get it back after a refresh.
I am aware that there are instructions on how to do this in JavaScript, but I cannot figure out how to do this in a Jupyter notebook. Any ideas?
Edit It seems I am not the first to have tried: https://github.com/nicolaskruchten/jupyter_pivottablejs/issues/34 and it is not possible with the current set up.
My hacky solution
I rewrote part of the pivottablejs package to add a "copy config" button. I put this code in an earlier cell in by Jupyter notebook, so the function would be accessible later:
Version for Google Colab:
!pip install pivottablejs
from pivottablejs import pivot_ui
from IPython.display import HTML
from IPython.display import IFrame
import json, io
TEMPLATE = u"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PivotTable.js</title>
<!-- external libs from cdnjs -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/pivot.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/pivot.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/d3_renderers.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/c3_renderers.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/export_renderers.min.js"></script>
<style>
body {font-family: Verdana;}
.node {
border: solid 1px white;
font: 10px sans-serif;
line-height: 12px;
overflow: hidden;
position: absolute;
text-indent: 2px;
}
.c3-line, .c3-focused {stroke-width: 3px !important;}
.c3-bar {stroke: white !important; stroke-width: 1;}
.c3 text { font-size: 12px; color: grey;}
.tick line {stroke: white;}
.c3-axis path {stroke: grey;}
.c3-circle { opacity: 1 !important; }
.c3-xgrid-focus {visibility: hidden !important;}
</style>
</head>
<body>
<script type="text/javascript">
$(function(){
$("#output").pivotUI(
$.csv.toArrays($("#output").text())
, $.extend({
renderers: $.extend(
$.pivotUtilities.renderers,
$.pivotUtilities.c3_renderers,
$.pivotUtilities.d3_renderers,
$.pivotUtilities.export_renderers
),
hiddenAttributes: [""]
}
, {
onRefresh: function(config) {
var config_copy = JSON.parse(JSON.stringify(config));
//delete some values which are functions
delete config_copy["aggregators"];
delete config_copy["renderers"];
//delete some bulky default values
delete config_copy["rendererOptions"];
delete config_copy["localeStrings"];
$("#output2").text(JSON.stringify(config_copy, undefined, 2));
}
}
, %(kwargs)s
, %(json_kwargs)s)
).show();
});
</script>
<div id="output" style="display: none;">%(csv)s</div>
<textarea id="output2"
style="float: left; width: 0px; height: 0px; margin: 0px; opacity:0;" readonly>
</textarea>
<button onclick="copyTextFunction()">Copy settings</button>
<script>
function copyTextFunction() {
var copyText = document.getElementById("output2");
copyText.select();
document.execCommand("copy");
}
</script>
</body>
</html>
"""
def pivot_cht_html(df, outfile_path = "pivottablejs.html", url="",
width="100%", height="500",json_kwargs='', **kwargs):
with io.open(outfile_path, 'wt', encoding='utf8') as outfile:
csv = df.to_csv(encoding='utf8')
if hasattr(csv, 'decode'):
csv = csv.decode('utf8')
outfile.write(TEMPLATE %
dict(csv=csv, kwargs=json.dumps(kwargs),json_kwargs=json_kwargs))
IFrame(src=url or outfile_path, width=width, height=height)
return HTML(outfile_path)
Version for standard Jupyter notebook:
#this is my custom version of pivottablejs, it allows you to save your analysis
!pip install pivottablejs
from pivottablejs import pivot_ui
from IPython.display import HTML
from IPython.display import IFrame
import json, io
TEMPLATE = u"""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PivotTable.js</title>
<!-- external libs from cdnjs -->
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.11/c3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery-csv/0.71/jquery.csv-0.71.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/pivot.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/pivot.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/d3_renderers.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/c3_renderers.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pivottable/2.19.0/export_renderers.min.js"></script>
<style>
body {font-family: Verdana;}
.node {
border: solid 1px white;
font: 10px sans-serif;
line-height: 12px;
overflow: hidden;
position: absolute;
text-indent: 2px;
}
.c3-line, .c3-focused {stroke-width: 3px !important;}
.c3-bar {stroke: white !important; stroke-width: 1;}
.c3 text { font-size: 12px; color: grey;}
.tick line {stroke: white;}
.c3-axis path {stroke: grey;}
.c3-circle { opacity: 1 !important; }
.c3-xgrid-focus {visibility: hidden !important;}
</style>
</head>
<body>
<script type="text/javascript">
$(function(){
$("#output").pivotUI(
$.csv.toArrays($("#output").text())
, $.extend({
renderers: $.extend(
$.pivotUtilities.renderers,
$.pivotUtilities.c3_renderers,
$.pivotUtilities.d3_renderers,
$.pivotUtilities.export_renderers
),
hiddenAttributes: [""]
}
, {
onRefresh: function(config) {
var config_copy = JSON.parse(JSON.stringify(config));
//delete some values which are functions
delete config_copy["aggregators"];
delete config_copy["renderers"];
//delete some bulky default values
delete config_copy["rendererOptions"];
delete config_copy["localeStrings"];
$("#output2").text(JSON.stringify(config_copy, undefined, 2));
}
}
, %(kwargs)s
, %(json_kwargs)s)
).show();
});
</script>
<div id="output" style="display: none;">%(csv)s</div>
<textarea id="output2"
style="float: left; width: 0px; height: 0px; margin: 0px; opacity:0;" readonly>
</textarea>
<button onclick="copyTextFunction()">Copy settings</button>
<script>
function copyTextFunction() {
var copyText = document.getElementById("output2");
copyText.select();
document.execCommand("copy");
}
</script>
</body>
</html>
"""
def pivot_cht_ui(df, name, url="",
width="100%", height="500",json_kwargs='', **kwargs):
print(name)
outfile_path = name + '.html'
with io.open(outfile_path, 'wt', encoding='utf8') as outfile:
csv = df.to_csv(encoding='utf8')
if hasattr(csv, 'decode'):
csv = csv.decode('utf8')
outfile.write(TEMPLATE %
dict(csv=csv, kwargs=json.dumps(kwargs),json_kwargs=json_kwargs))
return IFrame(src=url or outfile_path, width=width, height=height)
This enables you to make a chart as so (google colab version, slightly different for Jupyter notebook version):
pivot_cht_html(d1)
Which loads a blank chart which you can manually configure (below image is configured). Note the "copy settings" button:
If you press the button it copies a JSON of the config, which you can then put back into the charting function so that it runs your configured chart:
pivot_cht_html(d1,json_kwargs="""
{
"derivedAttributes": {},
"hiddenAttributes": [
""
],
"hiddenFromAggregators": [],
"hiddenFromDragDrop": [],
"menuLimit": 500,
"cols": [
"weeks"
],
"rows": [],
"vals": [
"resurrected_90d"
],
"rowOrder": "key_a_to_z",
"colOrder": "key_a_to_z",
"exclusions": {},
"inclusions": {},
"unusedAttrsVertical": 85,
"autoSortUnusedAttrs": false,
"sorters": {},
"inclusionsInfo": {},
"aggregatorName": "Average",
"rendererName": "Line Chart"
}
""")
This is far from ideal... Ideally this should be added to the pivottablejs package as a PR. If I get time I will try to do this!

Incorporating CSS into HTML for my Python Script

I am fairly new to the world of coding and python and i am working on an automation which would trigger automatic emails via outlook
The code is use is as follows
import win32com.client as win32
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,20,size=(10, 4)), columns=list('ABCD'))
outlook = win32.Dispatch('outlook.application')
mail = outlook.CreateItem(0)
mail.To = 'user#email.com'
mail.Subject = 'Insert Subject'
table1=df.to_html()
mail.HTMLBody = """
<html>
<head></head>
<link rel="stylesheet" type="text/css" href="df_style.css"/>
<body>
<h4>Table 1: Table data<h4>
""" + table1 + """
</body>
</html>
"""
mail.Send()
Ive saved my CSS on the desktop as df_style which is as follows
.mystyle {
font-size: 11pt;
font-family: Arial;
border-collapse: collapse;
border: 1px solid silver;
}
.mystyle td, th {
padding: 5px;
}
.mystyle tr:nth-child(even) {
background: #E0E0E0;
}
.mystyle tr:hover {
background: silver;
cursor: pointer;
}
But the changes to the table is not happening and i am left with the plain old table.
I am not really sure whats going wrong here...
I can think of two approaches:
make sure the path to your css file is set correctly, you may need to use something like:
css_file_path = str(os.path.dirname(file) + '/' + 'df_style.css')
and then:
mail.HTMLBody = f"""
<html>
<head></head>
<link rel="stylesheet" type="text/css" href={css_file_path}"/>
<body>
<h4>Table 1: Table data<h4>
""" + table1 + """
</body>
</html>
"""
2.use style tag in head section:
f"""
<!doctype html>
<html>
<head>
<style>
body {{
background-color: #ffffff;
}}
</style>
</head>
<body>
....
</body>
</html>
Note: if you are using f string, remember to use {{ instead of one for your styles.

Add <style> element to an HTML using Python Dominate library

I'm trying to generate an HTML with the dominate package in Python. For the format, I have to add a short CSS content into the <style> tag. However, the only documentation I can find is the GitHub page and that page doesn't have any function related to adding the <style>.
PS: Here's an image
Is this what you are after? from here
import dominate
from dominate.tags import link, script, style
doc = dominate.document(title='Dominate your HTML')
with doc.head:
link(rel='stylesheet', href='style.css')
script(type='text/javascript', src='script.js')
style("""\
body {
background-color: #F9F8F1;
color: #2C232A;
font-family: sans-serif;
font-size: 2.6em;
margin: 3em 1em;
}
""")
print(doc.render(pretty=True))
It yields;
<!DOCTYPE html>
<html>
<head>
<title>Dominate your HTML</title>
<link href="style.css" rel="stylesheet">
<script src="script.js" type="text/javascript"></script>
<style> body {
background-color: #F9F8F1;
color: #2C232A;
font-family: sans-serif;
font-size: 2.6em;
margin: 3em 1em;
}
</style>
</head>
<body></body>
</html>

Categories

Resources