Сгенерировать HTML для PDF с использованием xhtml2pdf в проекте DjangoPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Сгенерировать HTML для PDF с использованием xhtml2pdf в проекте Django

Сообщение Anonymous »

У меня есть HTML -страница, содержащая несколько таблиц. При преобразовании в PDF с использованием xhtml2pdf он работает нормально, если расширено только несколько таблиц. Однако, если я расширяю больше таблиц, я сталкиваюсь с ограничением размера, где PDF оказывается пустым, если содержание превышает определенный размер (30 МБ). views.py < Br />

Код: Выделить всё

def generate_pdf(request):
template_path = 'app.html'
context = {
'data': 'This is dynamic data passed to the template'
}

pdf_stylesheets = """

@page {
size: A4 landscape;
margin: 1.5cm;
}

.table-wrapper {
width: 100%;
}

table {
width: 100%;
border-collapse: collapse;
table-layout: fixed !important;
}

thead {
display: table-header-group;
}

tbody {
page-break-inside: avoid !important;
break-inside: avoid !important;
}

tr {
page-break-inside: avoid !important;
break-inside: avoid !important;
}

td {
padding: 8px;
border: 1px solid #ddd;
font-size: 14px;
vertical-align: top;
}

/* Column widths */
td:nth-child(1) { width: 10%; }
td:nth-child(2) { width: 15%; }
td:nth-child(3) { width: 10%; }
td:nth-child(4) {
width: 45%;
max-width: 45%;
word-wrap: break-word !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
white-space: pre-wrap !important;
}
td:nth-child(5) { width: 20%; }

.message-cell {
position: relative;
max-width: 45%;
word-wrap: break-word !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
white-space: pre-wrap !important;
}

.message-content {
display: inline-block;
width: 100%;
word-wrap: break-word !important;
word-break: break-word !important;
overflow-wrap: break-word !important;
white-space: pre-wrap !important;
line-height: 1.4;
}

th {
padding: 8px;
background-color: #355b7a;
color: white;
border: 1px solid #ddd;
font-size: 14px;
}

@media print {
table {
table-layout: fixed !important;
}

thead {
display: table-header-group !important;
}

tbody {
page-break-inside: avoid !important;
break-inside: avoid !important;
display: block !important;
min-height: fit-content !important;
}

tr {
page-break-inside: avoid !important;
break-inside: avoid !important;
}

td {
border: 0.5pt solid #ddd !important;
font-size: 14px !important;
}

.message-cell, .message-content {
page-break-inside: avoid !important;
break-inside: avoid !important;
}

* {
-webkit-print-color-adjust: exact !important;
print-color-adjust: exact !important;
}
}

"""

html = render_to_string(template_path, context)
html = pdf_stylesheets + html

response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment;  filename="app.pdf"'

pdf_options = {
'page-size': 'A4',
'orientation': 'Landscape',
'margin-top': '1.5cm',
'margin-right': '1.5cm',
'margin-bottom': '1.5cm',
'margin-left': '1.5cm',
'encoding': 'UTF-8',
'keep-with-next': 'true',
'no-split-tables': 'true',
'enable-smart-shrinking': 'true',
'print-media-type': 'true'
}

pisa_status = pisa.CreatePDF(
html.encode('UTF-8'),
dest=response,
encoding='UTF-8',
show_error_as_pdf=True,
pdf_options=pdf_options
)

if pisa_status.err:
return HttpResponse('We had some errors 
' + html + '')

return response
< /code>
шаблон HTML < /p>
{% load static %}



Test Report



body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f5f5f5;
}

.container {
display: flex;
flex-direction: column;
align-items: left;
margin: 0;
padding: 0;
}

.header-content {
width: 100%;
display: flex;
flex-direction: row;
justify-content: space-between;
margin: 0;
padding: 0;
}

h1 {
position: absolute;
left: 50%;
transform: translateX(-50%);
font-size: 1.5em;
}

.environment-details {
align-self: flex-start;
color: black;
font-size: 0.9em;
}

header {
background: #5ea3db;
color: white;
padding-top: 10px;
min-height: 60px;
border-bottom: #e8491d 3px solid;
}

.header-buttons {
position: absolute;
top: 2%;
right: 0;
transform: translateY(-50%);
display: flex;
gap: 3px;
}

.header-buttons button {
border: none;
border-radius: 7px;
padding: 5px 10px;
font-size: 14px;
transition-duration: 0.4s;
cursor: pointer;
}

.table-container {
width: 95%;
margin: 20px auto;
background: white;
padding: 15px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0,0,0,0.4);
}

.table-wrapper {
width: auto;
overflow-x: auto;
-webkit-overflow-scrolling: touch;
margin-bottom: 15px;
page-break-inside: avoid;
overflow: visible;
}

.main_table {
min-width: 100%;
margin-bottom: 15px;
}

.main_table th {
background-color: #355b7a;
color: white;
font-size: 0.9em;
white-space: nowrap;
padding: 8px 15px;
position: sticky;
top: 0;
}

.main_table td {
padding: 8px 15px;
text-align: justify;
font-size: 0.8em;
white-space: nowrap;
}
.main_table td:nth-child(1) {
width: 40%;
word-break: break-word;
white-space: normal;
overflow-wrap: break-word;
}
.main_table td:nth-child(2) { width: 10%; }
.main_table td:nth-child(3) { width: 15%; }
.main_table td:nth-child(4) { width: 15%;  }
.main_table td:nth-child(5) {
width: 20%;
word-break: break-word;
white-space: normal;
overflow-wrap: break-word;
}

.summary_table td {
padding: 15px;
font-size: 0.8em;
}

table {
border-collapse: collapse;
background-color: white;
}

table, th, td {
border: 1px solid #ddd;
}

tr:nth-child(even) {
background-color: #f2f2f2;
}

.table-wrapper::-webkit-scrollbar {
height: 8px;
}

.table-wrapper::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}

.table-wrapper::-webkit-scrollbar-thumb {
background: #888;
border-radius: 4px;
}

.table-wrapper::-webkit-scrollbar-thumb:hover {
background: #555;
}
/* @media print {
body { zoom: 0.75; }
} */
@media print {
body {
margin: 0;
padding: 0;
}

.page-break {
page-break-before: always;
}

table, img {
page-break-inside: avoid;
}
}







TEST REPORT

Project Name:[/b] {{ project_name }}[b]
Environment:[/b] {{environment}}[b]
Verification Type:[/b] {{VERIFICATION_TYPE}}




{% if log_file_name %}
[url={{ log_file_name }}]Robot Log[/url]
{% else %}
Robot Log Not Available
{% endif %}

Download PDF




This report includes the test case details and individual summary tables for each test case.

{{ main_table_html|safe }}

{% for table in summary_tables_html %}

{{ table|safe }}

{% endfor %}





const script = document.createElement('script');
script.src = "https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js";
script.onload = function () {
document.getElementById('downloadBtn').addEventListener('click', function() {
// Temporarily remove collapsed tables
document.querySelectorAll('details:not([open])').forEach(detail => {
detail.style.display = 'none';
});

const element = document.body;
const opt = {
margin:       [0.2, 0.2, 0.2, 0.2],
filename:     'test_report.pdf',
image:        { type: 'jpeg', quality: 0.98 },
html2canvas:  { scale: 4, scrollX: 0, scrollY: 0, useCORS: true },
jsPDF:        { unit: 'in', format: 'a4', orientation: 'landscape' }
};

// Generate and estimate PDF size before downloading
html2pdf().from(element).set(opt).toPdf().output('datauristring').then(dataUri => {
let estimatedSizeKB = (dataUri.length * (3 / 4)) / 1024; // Convert Base64 size to KB
console.log("PDF Size (KB):", estimatedSizeKB);

// If the estimated size is too large, show an alert and stop the process
if (estimatedSizeKB >= 100 &&  estimatedSizeKB  {
detail.style.display = '';
});

return; // Stop execution, do NOT generate the PDF
}

// If the size is acceptable, proceed with the download
html2pdf().from(element).set(opt).save().then(() => {
// Restore hidden elements after generating the PDF
document.querySelectorAll('details').forEach(detail => {
detail.style.display = '';
});
});
});
});
};
document.head.appendChild(script);



Как я могу гарантировать, что большие PDF -файлы загружаются правильно?

Подробнее здесь: https://stackoverflow.com/questions/794 ... go-project
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»