relorer / htmltoqpdf Goto Github PK
View Code? Open in Web Editor NEWHTMLToQPDF is an extension for QuestPDF that allows to generate PDF from HTML
License: MIT License
HTMLToQPDF is an extension for QuestPDF that allows to generate PDF from HTML
License: MIT License
Hello,
I think this library will be good if will can transfer all html tags
I was trying this HTML
<!DOCTYPE html>
<html>
<head>
<title> GeeSuthSoftCloud - View Docuemnt </title>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta http-equiv="content-type" content="text-html; charset=utf-8">
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@500&display=swap" rel="stylesheet">
<style type="text/css">
html,
body,
{
margin: 0;
padding: 0;
border: 0;
font: inherit;
font-size: 100%;
vertical-align: baseline;
font-family: 'Tajawal', sans-serif;
}
html {
line-height: 1;
}
ol,
ul {
list-style: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
caption,
th,
td {
text-align: left;
font-weight: normal;
vertical-align: middle;
}
q,
blockquote {
quotes: none;
}
q:before,
q:after,
blockquote:before,
blockquote:after {
content: "";
content: none;
}
a img {
border: none;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
body {
font-family: 'Source Sans Pro', sans-serif;
font-weight: 300;
font-size: 12px;
margin: 0;
padding: 0;
}
body a {
text-decoration: none;
color: inherit;
}
body a:hover {
color: inherit;
opacity: 0.7;
}
body .container {
min-width: 500px;
margin: 0 auto;
padding: 0 20px;
}
body .clearfix:after {
content: "";
display: table;
clear: both;
}
body .left {
float: left;
}
body .right {
float: right;
}
body .helper {
display: inline-block;
height: 100%;
vertical-align: middle;
}
body .no-break {
page-break-inside: avoid;
}
header {
margin-top: 20px;
margin-bottom: 50px;
}
header figure {
float: left;
width: 60px;
height: 60px;
margin-right: 10px;
background-color: #0b6351;
border-radius: 50%;
text-align: center;
}
header figure img {
margin-top: 13px;
}
header .company-address {
float: left;
max-width: 150px;
line-height: 1.7em;
}
header .company-address .title {
color: #0b6351;
font-weight: 400;
font-size: 1.5em;
text-transform: uppercase;
}
header .company-contact {
float: right;
height: 60px;
padding: 0 10px;
background-color: #0b6351;
color: white;
}
header .company-contact span {
display: inline-block;
vertical-align: middle;
}
header .company-contact .circle {
width: 20px;
height: 20px;
background-color: white;
border-radius: 50%;
text-align: center;
}
header .company-contact .circle img {
vertical-align: middle;
}
header .company-contact .phone {
height: 100%;
margin-right: 20px;
}
header .company-contact .email {
height: 100%;
min-width: 100px;
text-align: right;
}
section .details {
margin-bottom: 55px;
}
section .details .client {
width: 50%;
line-height: 20px;
}
section .details .client .name {
color: #0b6351;
}
section .details .data {
width: 50%;
text-align: right;
}
section .details .title {
margin-bottom: 15px;
color: #0b6351;
font-size: 3em;
font-weight: 400;
text-transform: uppercase;
}
section table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
font-size: 0.9166em;
}
section table .qty,
section table .unit,
section table .total {
width: 15%;
}
section table .sn {
width: 5px;
background: #0b6351;
}
section table .desc {
width: 50%;
}
section table thead {
display: table-header-group;
vertical-align: middle;
border-color: inherit;
}
section table thead th {
padding: 5px 10px;
background: #0b6351;
border-bottom: 5px solid #FFFFFF;
border-right: 0px solid #FFFFFF;
text-align: right;
color: white;
font-weight: 400;
text-transform: uppercase;
}
section table thead th:last-child {
border-right: none;
}
section table thead .desc {
text-align: right;
}
section table thead .qty {
text-align: center;
}
section table tbody td {
padding: 10px;
background: #E8F3DB;
color: #777777;
text-align: right;
border-bottom: 5px solid #FFFFFF;
border-right: 4px solid #E8F3DB;
}
section table tbody td:last-child {
border-right: none;
}
section table tbody h3 {
margin-bottom: 5px;
color: #0b6351;
font-weight: 600;
}
section table tbody .desc {
text-align: right;
}
section table tbody .qty {
text-align: center;
}
section table.grand-total {
margin-bottom: 45px;
}
section table.grand-total td {
padding: 5px 10px;
border: none;
color: #777777;
text-align: right;
}
section table.grand-total .desc {
background-color: transparent;
}
section table.grand-total tr:last-child td {
font-weight: 600;
color: #0b6351;
font-size: 1.18181818181818em;
}
footer {
margin-bottom: 20px;
}
footer .thanks {
margin-bottom: 40px;
color: #0b6351;
font-size: 1.16666666666667em;
font-weight: 600;
}
footer .notice {
margin-bottom: 25px;
}
footer .end {
padding-top: 5px;
border-top: 2px solid #0b6351;
text-align: center;
}
p {
color: black;
font-weight: bold;
}
.docname {
text-align: center;
padding-bottom: 10px;
height: auto;
}
.docname p {
background-color: #E8F3DB;
/* Second => #E8F3DB */
color: #0b6351;
height: 30px;
font-size: 25px;
}
.sn {
background-color: #0b6351;
color: white
}
</style>
<style>
@media print {
.print-bar {
display: none;
}
}
</style>
</head>
<body dir="rtl">
<div class="print-bar" style="text-align: end;padding: 15px;">
<input type="button" value="Print - " onClick="window.print()">
</div>
<section>
<header class="clearfix">
<div class="container">
<div class="company-contact">
<div class="phone right">
</div>
<div class="email left">
<span class="circle">
<a href="mailto: [email protected]"> [email protected]</a>
<span class="helper"></span>
</div>
</div>
<figure>
</figure>
<div class="company-address">
<p>
<br>
</p>
<p>
VAT : 12345678912365
</p>
</div>
</div>
</header>
</section>
</body>
<section class="container">
<div class="docname">
<p>
</p>
</div>
</section>
<section>
<div class="container">
<div class="details clearfix">
<div class="client">
<p> :</p>
<p class="name"> 111111111111110 </p>
<p> </p>
<a href="mailto: [email protected]">[email protected]</a>
</div>
<div class="client">
<p> :</p>
<p class="name"> </p>
</div>
<div class="client">
<p> :</p>
<p class="name"> </p>
</div>
<div class="client">
<p> :</p>
<p class="name"> </p>
</div>
<div class="client left" style="margin-top: -130px;">
<div class="left">
<div class="title">INV#4 </div>
<div class="date">
21-03-2022 09:00
</div>
</div>
<div class="left">
<div style="text-align: end;">
<img style="height: 100px;" src="data:image/png;charset=utf-8;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADIAQMAAACXljzdAAAABlBMVEX///8AAABVwtN+AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAqUlEQVRYhe2UUQ6AMAhDuf+lMZOWqfMAvsWakG3PnwZoxK+PK0vjNL6+Ycmtvr3RyHCWevWNT+x0GzIOWxDVc6FeZ5RFlA3pvi0ZwiKW+7WKRU6X9qpEJ5PaqPpHdt05Jol2l20bTKpjfosZF1BS3XLRQJKJbXmrLlaJ5J7ktV9ooprZt24pk8zx6y3bgFTPIlenTKLi1AAT8chO8yATJ8V0+swQFPn1YR0a0xlKXJm0PQAAAABJRU5ErkJggg=="
alt="">
</div>
</div>
</div>
</div>
<table border="0" cellspacing="0" cellpadding="0" class="right">
<thead>
<tr>
<th class="sn">Sn </th>
<th class="desc">Item Code </th>
<th class="qty">Unit Name </th>
<th class="qty">Quantity </th>
<th class="unit">Unit price </th>
<th class="unit">Discount </th>
<th class="total">Total </th>
</tr>
</thead>
<tbody>
<tr>
<td class="sn">
1
</td>
<td class="desc">
<h3>cod507</h3>
</td>
<td class="qty"></td>
<td class="qty">50.00</td>
<td class="unit"> 1000.00 </td>
<td class="unit">0.00 </td>
<td class="total"> 57500.0000 </td>
</tr>
</tbody>
</table>
<div class="no-break">
<table class="grand-total">
<tbody>
<tr>
<td class="desc"></td>
<td class="qty"></td>
<td class="unit"> 50000.0000 </td>
<td class="total"> SUBTOTAL </td>
</tr>
<tr>
<td class="desc"></td>
<td class="qty"></td>
<td class="unit"> 7500.00 </td>
<td class="total">
TAX
</td>
</tr>
<tr>
<td class="desc"></td>
<td class="qty"></td>
<td class="unit"> 0.0000 </td>
<td class="total"> DISCOUNT </td>
</tr>
<tr>
<td class="desc"></td>
<td class="qty"></td>
<td class="unit"> 57500.0000 </td>
<td class="total"> GRAND TOTAL </td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<body>
<section>
<footer>
<div class="container">
<div class="thanks">Thank you! </div>
<div class="notice">
<div> NOTICE :</div>
<div> Note </div>
</div>
<div class="end">Invoice was created on a computer and is valid without the signature and seal.</div>
</div>
</footer>
</section>
</body>
</html>
Hi I've found a problem happend in a situation like this:
sit, amet consectetur adipisicing elit.
The result is that the system removes the whitespace before the b tag.
To be sure I've tested it with the example project like this:
With the result:
As you can see in the image the whitespace before the bold has disappeared.
Looking for the reason we found in the ParagraphComponent.cs class two trims that apparently generates the issue:
I really don't know the code, but it seems the system generates a quest pdf component for each tag and the "b" tag is included in this Paragraph component.
Maybe those trims shouldn't be applied in line formatting elements like b, i etc.
Would it be possible to add a feature of alignment of blocks such as
<p align="center">
or similar for other blocks and alignment? (Left, Right, Top, Middle, etc.) / (h1, h2, etc.)?
Also font attributes such as color, size, etc. ?
Thank you for all your work.
I am receiving an exception while trying to render an <ul>
list.
The exeption:
Method not found: 'QuestPDF.Infrastructure.IContainer QuestPDF.Fluent.ElementExtensions.Element(!!0, System.Func`2<QuestPDF.Infrastructure.IContainer,QuestPDF.Infrastructure.IContainer>)'.
Example content:
<p>A paragraph</p>
<ul>
<li>First item in the list</li>
</ul>
If I omit the <ul>
tag the PDF is generated successfully. I also tried the same content with the HTMLToQPDF.Example.exe downloaded from the project page and it works. Is there something I am missing?
table getting messed u
var html = "<table class=\"tiptap\" style=\"minWidth: 125px\"><colgroup><col><col><col><col><col></colgroup><tbody><tr><th colspan=\"1\" rowspan=\"2\"><p style=\"text-align: center\">ASCVD RISK </p><p style=\"text-align: center\">CATEGORY@</p></th><th colspan=\"2\" rowspan=\"1\"><p style=\"text-align: center\">CONSIDER THERAPY</p></th><th colspan=\"2\" rowspan=\"1\"><p style=\"text-align: center\">TREATMENT GOAL</p></th></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">LDL CHOLESTEROL</p><p style=\"text-align: center\">(LDL-C)(mg/dL)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">NON HDL CHLOESTEROL</p><p style=\"text-align: center\">(NON HDL-C) (mg/dL)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">LDL CHOLESTEROL</p><p style=\"text-align: center\">(LDL-C)(mg/dL)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">NON HDL CHLOESTEROL</p><p style=\"text-align: center\">(NON HDL-C) (mg/dL)</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">Extreme (A)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=50</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=80</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><50 (Indispensable)</p><p style=\"text-align: center\"><30 (Optional)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><80</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">Extreme (B)</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=30</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=60</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><30</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><60</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">Very High</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=50</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=80</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><50</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><80</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">High</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=70</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=100</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><70</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><100</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">Moderate</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=100</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=130</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><100</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><130</p></td></tr><tr><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">Low</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=130*</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\">>=160*</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><100</p></td><td colspan=\"1\" rowspan=\"1\" style=\"background-color: null\"><p style=\"text-align: center\"><130</p></td></tr></tbody></table>";
var document = Document.Create(container =>
{
container.Page(page =>
{
page.Content().Column(col =>
{
col.Item().HTML(handler =>
{
handler.SetTextStyleForHtmlElement("table", TextStyle.Default.FontSize(12));
handler.SetHtml(html);
});
});
});
});
document.ShowInPreviewer();
@Relorer tried this but getting exception
System.MissingMethodException
HResult=0x80131513
Message=Method not found: 'QuestPDF.Infrastructure.IContainer QuestPDF.Fluent.ElementExtensions.Element(QuestPDF.Infrastructure.IContainer, System.Func`2<QuestPDF.Infrastructure.IContainer,QuestPDF.Infrastructure.IContainer>)'.
Source=HTMLToQPDF
StackTrace:
at HTMLQuestPDF.Components.Tags.ListComponent.ApplyStyles(IContainer container)
at HTMLQuestPDF.Components.BaseHTMLComponent.Compose(IContainer container)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component, Action`1 handler)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component)
at HTMLQuestPDF.Components.BaseHTMLComponent.<ComposeMany>b__6_0(ColumnDescriptor col)
at QuestPDF.Fluent.ColumnExtensions.Column(IContainer element, Action`1 handler)
at HTMLQuestPDF.Components.BaseHTMLComponent.ComposeMany(IContainer container)
at HTMLQuestPDF.Components.BaseHTMLComponent.Compose(IContainer container)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component, Action`1 handler)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component)
at HTMLQuestPDF.Components.BaseHTMLComponent.<ComposeMany>b__6_0(ColumnDescriptor col)
at QuestPDF.Fluent.ColumnExtensions.Column(IContainer element, Action`1 handler)
at HTMLQuestPDF.Components.BaseHTMLComponent.ComposeMany(IContainer container)
at HTMLQuestPDF.Components.BaseHTMLComponent.Compose(IContainer container)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component, Action`1 handler)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component)
at HTMLQuestPDF.Components.BaseHTMLComponent.<ComposeMany>b__6_0(ColumnDescriptor col)
at QuestPDF.Fluent.ColumnExtensions.Column(IContainer element, Action`1 handler)
at HTMLQuestPDF.Components.BaseHTMLComponent.ComposeMany(IContainer container)
at HTMLQuestPDF.Components.BaseHTMLComponent.Compose(IContainer container)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component, Action`1 handler)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component)
at HTMLToQPDF.Components.HTMLComponent.Compose(IContainer container)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component, Action`1 handler)
at QuestPDF.Fluent.ComponentExtensions.Component[T](IContainer element, T component)
at HTMLQuestPDF.Extensions.HTMLComponentExtensions.HTML(IContainer container, Action`1 handler)
at ReportDesigner.Program.<>c__DisplayClass0_2.<Main>b__17(ColumnDescriptor test_column) in C:\Users\ReportDesigner\Program.cs:line 275
at QuestPDF.Fluent.ColumnExtensions.Column(IContainer element, Action`1 handler)
at ReportDesigner.Program.<>c__DisplayClass0_0.<Main>b__4(ColumnDescriptor column) in C:\Users\ReportDesigner\Program.cs:line 199
at QuestPDF.Fluent.ColumnExtensions.Column(IContainer element, Action`1 handler)
at ReportDesigner.Program.<>c__DisplayClass0_0.<Main>b__1(PageDescriptor page) in C:\Users\ReportDesigner\Program.cs:line 193
at QuestPDF.Fluent.PageExtensions.Page(IDocumentContainer document, Action`1 handler)
at ReportDesigner.Program.<>c__DisplayClass0_0.<Main>b__0(IDocumentContainer container) in C:\Users\ReportDesigner\Program.cs:line 22
at QuestPDF.Fluent.Document.Compose(IDocumentContainer container)
at QuestPDF.Drawing.DocumentGenerator.ConfigureContent(IDocument document, DocumentSettings settings, Boolean useOriginalImages)
at QuestPDF.Drawing.DocumentGenerator.RenderSingleDocument[TCanvas](TCanvas canvas, IDocument document, DocumentSettings settings)
at QuestPDF.Drawing.DocumentGenerator.RenderDocument[TCanvas](TCanvas canvas, IDocument document, DocumentSettings settings)
at QuestPDF.Drawing.DocumentGenerator.GeneratePreviewerContent(IDocument document)
at QuestPDF.Previewer.Extensions.<>c__DisplayClass1_0.<ShowInPreviewerAsync>g__GetPictures|4()
Every table has a border.
I used style, border = 0,
handler.SetContainerStyleForHtmlElement("table", t => t.Border(0f)); (and for good measure td, and tr).
Nothing works.
What am I doing wrong and how do I set the width of td elements?
After I just added the package, I ran it directly and reported this error. No matter how you adjust it, it won't work,The code is as follows:
string html = @"<!DOCTYPE html>
<html lang=""en"">
<head>
<meta charset=""UTF-8"">
<meta name=""viewport"" content=""width=device-width, initial-scale=1.0"">
<title>Document</title>
</head>
<body>
<h1>标题一</h1>
<img src=""https://file.ejiang.com:9001/childplat/resource/courseware/cover/9a2579ef-22af-4d9d-bd1a-5814df5107ca.jpg?size=m480"" />
</body>
</html>";
Document.Create(container =>
{
container.Page(page =>
{
page.Content().Column(col =>
{
col.Item().HTML(handler =>
{
handler.SetHtml(html);
});
});
});
}).GeneratePdf("123.pdf");
Console.WriteLine("OK");
Hi, I love using this library so far! Are there any plans to have a new release soon to include these changes for being able to use an IContainer instead of a PageDescriptor?
Hi,
Is it possible to convert the html ordered list with lower alpha?
i.e. instead of 1, 2, 3 the list is numbered as a, b, c ...
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.