I have an HTML page containing multiple tables. When converting it to a PDF using xhtml2pdf, it works fine if only a few tables are expanded. However, if I expand more tables, I run into a size limitation where the PDF turns out blank if the content exceeds a certain size(30Mb). Views.py def generate_pdf(request): template_path = 'app.html' context = { 'data': 'This is dynamic data passed to the template' } pdf_stylesheets = """ <style> @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; } } </style> """ 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 <pre>' + html + '</pre>') return response html template {% load static %} <html> <head> <meta charset="UTF-8"> <title>Test Report</title> </head> <style> 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; } } </style> </head> <body> <header> <div class="container"> <div class="header-content"> <h1>TEST REPORT</h1> <div class="environment-details"> <b>Project Name:</b> {{ project_name }}<br> <b>Environment:</b> {{environment}}<br> <b>Verification Type:</b> {{VERIFICATION_TYPE}}<br> </div> </div> <div class="header-buttons"> <button> {% if log_file_name %} <a href="{{ log_file_name }}" style="text-decoration: none; color: black;" target="_blank">Robot Log</a> {% else %} <span>Robot Log Not Available</span> {% endif %} </button> <button id="downloadBtn">Download PDF</button> </div> </div> </header> <div class="table-container"> <p style="text-align:center;">This report includes the test case details and individual summary tables for each test case.</p> <div class="table-wrapper"> {{ main_table_html|safe }} </div> <div> {% for table in summary_tables_html %} <div class="table-wrapper"> {{ table|safe }} </div> {% endfor %} </div> </div> </body> <script> 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 <= 300) { alert("The generated PDF is too large. Try again with fewer expanded test cases."); // Restore hidden elements after canceling the process document.querySelectorAll('details:not([open])').forEach(detail => { 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); </script> </html> How can I ensure that large PDFs download correctly? Continue reading...