Horizontally merge and divide cells in an HTML Table for Timetable based on the Data in Python File
I am not much familiar with Jinja, so this answer might not be the most efficient one.
By using basic hard coding in your Template.HTML file, I was able to achieve the results you are trying to. For this, I used the same code that was given by D-E-N
in your previous question.
I combined all the attributes of your object into a string
- An attribute is differentiated from another with
@
(like Course and Teacher) - Instead of using
space character
, I used a_
character to representspace character
in the attributes. - If one slot contains multiple objects, they are differentiated with
space character
(just like in the code provided byD-E-N
)
Here's the updated code of yours with these changes,
from typing import List
import pdfkit
from pdfkit.api import configuration
from jinja2 import FileSystemLoader, Environment
wkhtml_path = pdfkit.configuration(wkhtmltopdf = "C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe") #by using configuration you can add path value.
class section:
def __init__(self, id, course, section, instructor, room):
self.id = id
self.course = course
self.section = section
self.instructor = instructor
self.room = room
def generate_data():
data = {}
# For CS-1A
data["CS-1A"] = [["" for i in range(5)] for j in range(5)]
data["CS-1A"][0][0] += "[email protected]@Room_#2 "
data["CS-1A"][0][0] += "Applied_Physics@Bilal@Room_#1 "
data["CS-1A"][0][1] += "Programming_Fundamentals@Muhammad_Bilal@Room_#1 "
data["CS-1A"][0][3] += "Programming_Fundamentals_Lab@Mr._Abid@Lab_#01 "
data["CS-1A"][0][4] += "Programming_Fundamentals_Lab@Mr._Abid@Lab_#01 "
# You may change all these for testing purposes.
# data["CS-1A"][0][0].append(section(2, "Programming Fundamentals", "CS-1A", "Bilal", "Room #1"))
# data["CS-1A"][0][1].append(section(3, "Applied Physics", "CS-1A", "Muhammad Bilal", "Room #5"))
# obj = section(4, "Programming Lab", "CS-1A", "Mr. Abid", "Lab #01")
# data["CS-1A"][0][1].append(obj)
# data["CS-1A"][0][2].append(obj)
# data["CS-1A"][0][4].append(section(5, "English Communication", "CS-1A1", "Ms. Ayeza", "Cal Lab"))
# data["CS-1A"][0][4].append(section(6, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
# data["CS-1A"][1][1].append(section(7, "Linear Algebra", "CS-1A", "Ms. Zain", "Romm #2"))
# obj = section(8, "English Lab", "CS-1A", "Ms. Abida", "Lab #04")
# data["CS-1A"][1][3].append(obj)
# data["CS-1A"][1][4].append(obj)
# data["CS-1A"][2][0].append(section(9, "Social Studies", "CS-1A", "Mr. Zain Iqbal", "Room #14"))
# data["CS-1A"][2][4].append(section(10, "Programming Fundamentals", "CS-1A", "Bilal", "Room #15"))
# # No lectures on Thursday i.e. 3rd index
# obj = section(11, "English Lab", "CS-1A", "Ms. Abida", "Lab #03")
# data["CS-1A"][4][1].append(obj)
# data["CS-1A"][4][2].append(obj)
# data["CS-1A"][4][2].append(section(12, "English Communication", "CS-1A1", "Ms. Ayeza", "Room #3"))
# data["CS-1A"][4][2].append(section(13, "English Communication", "CS-1A2", "Ms. Ayesha", "GP Lab"))
#
#
#
# # For CS-1B
# data["CS-1B"] = [[[] for i in range(5)] for j in range(5)]
#
# data["CS-1B"][0][1].append(section(14, "Advance Programming", "CS-1B", "Mr. Ali Hassan", "Room #2"))
# data["CS-1B"][0][2].append(section(15, "English Comprehension and Communication", "CS-1B", "Mr. Bilal", "Room #1"))
# obj = section(15, "Software for Mobile and Devices", "CS-1B", "Mr. Jacob", "Room #5")
# data["CS-1B"][1][1].append(obj)
# data["CS-1B"][1][2].append(obj)
# data["CS-1B"][1][3].append(section(17, "Calculus and Geometrical Analytics", "CS-1B", "Ms. Nomi Khan", "Room #06"))
# data["CS-1B"][2][3].append(section(18, "Introduction to Information and Communication Technology - Lab", "CS-1B1", "Ms. Sarah Niaz", "Lab #01"))
# data["CS-1B"][2][3].append(section(19, "Introduction to Information and Communication Technology - Lab", "CS-1B2", "Ms. Julia John", "Lab #06"))
# data["CS-1B"][2][4].append(section(20, "English Comprehenseion and Communication", "Cs-1B", "Mr. Lionel Boyle", "Room #02"))
# data["CS-1B"][3][3].append(section(21, "Programming Fundamentals", "CS-1B", "Mr. Alex Niles", "Room #3"))
# data["CS-1B"][4][2].append(section(22, "Linear Algebra", "CS-1B", "Ms. Ayesha", "GP Lab"))
return data
def organise_input_data(elements: List[List[str]]) -> List[list]:
"""
Organises the input data to find double courses for easier use in templates
"""
new_elements = []
for day in elements:
last_course = None
course_list = []
index = 0
for course in day:
# cleanup data
course = course.strip().replace(" ", "<hr>")
# check if long course (and not lunch time)
if course != "" and course == last_course and index != 3:
course_list.remove((course, 1))
course_list.append((course, 2))
course_list.append(("none", 0))
else:
course_list.append((course.replace(" ", "<hr>"), 1))
last_course = course
index += 1
new_elements.append(course_list)
return new_elements
def generate_html(template, name: str, elements: List[list]) -> str:
new_elements = organise_input_data(elements=elements)
rendered = template.render(
name=name,
monday=new_elements[0],
tuesday=new_elements[1],
wednesday=new_elements[2],
thursday=new_elements[3],
friday=new_elements[4]
)
with open(f"out_{name}.html", "w+") as file:
file.write(rendered)
return rendered
def run(input_data):
# Init jinja
file_loader = FileSystemLoader('.')
env = Environment(loader=file_loader)
template = env.get_template('template.html')
full_text = ""
for name, elements in input_data.items():
full_text += generate_html(template=template, name=name, elements=elements)
pdfkit.from_string(full_text, "out.pdf", configuration = wkhtml_path)
if __name__ == '__main__':
data = generate_data()
run(data)
Major changes are done in the template.html
file to achieve what you are trying to achieve. Here's the Code,
<!DOCTYPE html>
<html>
<style>
.center
{
text-align: center;
}
.left
{
text-align: left;
margin-left: 6px;
/*margin-top: 10px;*/
}
.right
{
text-align: right; margin-right: 4px;
}
.teacher
{
margin-left: 4px;
}
td{
height:175px;
width:150px;
}
</style>
<body>
<!-- Heading -->
<h1 class="center">{{name}}</h1>
<!-- Table -->
<table border="5" cellspacing="5" align="center">
<!-- Day/Periods -->
<tr>
<td class="center" ><br>
<b>Day/Period</b></br>
</td>
<td class="center" >
<b>I</b>
</td>
<td class="center" >
<b>II</b>
</td>
<td class="center">
<b>III</b>
</td>
<td class="center">
<b>1:15-1:45</b>
</td>
<td class="center" >
<b>IV</b>
</td>
<td class="center" >
<b>V</b>
</td>
</tr>
<!-- Monday -->
<tr>
<td class="center">
<b>Monday</b></td>
{% for course in monday %}
{% if loop.index == 4 %}
<td rowspan="6" class="center">
<h2>L<br>U<br>N<br>C<br>H</h2>
</td>
{% endif %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Tuesday -->
<tr>
<td class="center">
<b>Tuesday</b>
</td>
{% for course in tuesday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Wednesday -->
<tr>
<td class="center">
<b>Wednesday</b>
</td>
{% for course in wednesday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Thursday -->
<tr>
<td class="center">
<b>Thursday</b>
</td>
{% for course in thursday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
<!-- Friday -->
<tr>
<td class="center">
<b>Friday</b>
</td>
{% for course in friday %}
{% if course[1] != 0 %}
<td colspan={{course[1]}}>
{% set count = [] %}
{%- for y in range(0, 5) -%}
{%- if count|length < course[0]|length -%}
<p class="left">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "right">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
{% set __ = count.append(1) %}
<p class = "teacher">
{%- for z in range(count|length, course[0]|length) -%}
{%- if course[0][count|length] == '@' -%}
{%- else -%}
{% set __ = count.append(1) %}
{%- if course[0][count|length-1] == '_' -%}
{{' '}}
{%- else -%}
{{course[0][count|length-1]}}
{%- endif -%}
{%- endif -%}
{%- endfor -%}
</p>
<!-- <p class="left">{{course[0]}}</p>
<p class="right">{{course[1]}}</p>
<p class="teacher">{{course[2]}}</p> -->
{%- endif -%}
{%- endfor -%}
</td>
{% endif %}
{% endfor %}
</tr>
</table>
</body>
</html>
This produces the following result,