Im trying to generate a PDF using the PDFExport component but have run into an issue with the flow of the content. My document has two sections aligned using flexbox and displayed side by side. I want to be able to support multiple pages using the components auto-page break detection, however whenever the content of the section on the left (logically the first of the two sections in the DOM) overflows the first page, it forces the second section to the right of it onto its own page, leaving a large gap on the right side of the document where it should've been.
Since the content of these sections is dynamic, its isn't really feasible to manually set a page break, however I think the problem is more fundamental than that. My interpretation of this issue is that even though you may use something like flexbox or widths/floats to align content into multiple columns, when processed into a PDF, the component doesn't maintain those alignments in the multi-page scenario, but instead causes each column to be on its own page.
Is there something I can do to prevent this? Should I look into using the GridPDFExport component instead and just hack at the styling to remove the grid lines since I'm expecting a layout that's based around columns? If my example was unclear please let me know and I'll try to provide a more concrete one, thanks for any help
9 Answers, 1 is accepted
Thank you for the information.
In order to provide more to the point suggestions please provide the following details:
1) The HTML used on the page, so we have a better understanding of the elements that construct the page.
2) How would you expect the page to be exported, for example, if the first section is too large, and has to be on two pages? The first page to have both side by side and the rest of the first section to be alone on the next page, is this the correct one?
Regards,
Stefan
Progress Telerik
Hi Stefan,
For the HTML, an easy example of this would be to take the multi-page example in the "Automatic Page Splitting / Overview" section found here, opening the example given in StackBlitz, and replacing the given code in main.js with the following:
import React from
'react'
;
import ReactDOM from
'react-dom'
;
import { PDFExport } from
'@progress/kendo-react-pdf'
;
class App extends React.Component {
pdfExportComponent;
render() {
const parentStyle = {
display:
'flex'
};
const childStyle = {
padding:
'16px'
}
return
(
<div>
<div className=
"example-config"
>
<button className=
"k-button"
onClick={() => {
this
.pdfExportComponent.save(); }}>
Export PDF
</button>
</div>
<PDFExport
paperSize=
"A4"
margin=
"2cm"
ref={(component) =>
this
.pdfExportComponent = component}
>
<div style={parentStyle}>
<div style={childStyle}>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci.
</p>
</div>
<div style={childStyle}>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci.
</p>
</div>
</div>
</PDFExport>
</div>
);
}
}
ReactDOM.render(
<App />,
document.querySelector(
'my-app'
)
);
With this, you should get two columns of text, and when exported to PDF, it should look like the attached file "columns-one-page.pdf". The issue arise when you increase the amount of content in the columns, particularly the one that comes first logically in the DOM. What I would expect (or would like to see), is when there is too much text in either/both columns, they overflow onto the next page while maintaining a similar layout to the previous example. So say the first column has too much text: both it and the second column should be together on the first page, then the first column should overflow straight down into the second page. Instead, as you can see with this example below, it pushes the second column off the first page, and ruins the layout in the process:
import React from
'react'
;
import ReactDOM from
'react-dom'
;
import { PDFExport } from
'@progress/kendo-react-pdf'
;
class App extends React.Component {
pdfExportComponent;
render() {
const parentStyle = {
display:
'flex'
};
const childStyle = {
padding:
'16px'
}
return
(
<div>
<div className=
"example-config"
>
<button className=
"k-button"
onClick={() => {
this
.pdfExportComponent.save(); }}>
Export PDF
</button>
</div>
<PDFExport
paperSize=
"A4"
margin=
"2cm"
ref={(component) =>
this
.pdfExportComponent = component}
>
<div style={parentStyle}>
<div style={childStyle}>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci.
</p>
</div>
<div style={childStyle}>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer felis libero, lobortis ac rutrum quis, varius a velit. Donec lacus erat, cursus sed porta quis, adipiscing et ligula. Duis volutpat, sem pharetra accumsan pharetra, mi ligula cursus felis, ac aliquet leo diam eget risus. Integer facilisis, justo cursus venenatis vehicula, massa nisl tempor sem,
in
ullamcorper neque mauris
in
orci.
</p>
</div>
</div>
</PDFExport>
</div>
);
}
}
ReactDOM.render(
<App />,
document.querySelector(
'my-app'
)
);
Check the attached "columns-multi-page.pdf" file for this export. I've tried to achieve this column effect multiple ways- changing up the ordering of objects using flexbox (just doesn't work), absolute positioning (the second column stays on the first page if the first column is too long, but if the second column is too long it gets cut off since absolute positioning isn't supported for multi page), floating left/right, etc. The only thing I can think of at this point would be to somehow detect/keep track of the height of my dynamic content and manually do the page breaking myself when the PDF is about to be exported, but I'd like to avoid that if possible.
If there's any possible way to do overflowing columns, or if you've ever seen any examples of something like, please let me know! Thank you
Thank you for the additional details.
In the provided code the DIVs are positioned one after another, so I assume the code that is positioning them is missing. I noticed that it says something about absolute positioning, which is a limitation of the PDF export.
This shows the example looks after using the provided code:
https://stackblitz.com/edit/react-ntmmcv?file=app/main.js
Please check the following article about the page break limitation regarding the styles as the elements. This could prove helpful when deciding how to construct the HTML, so it can be exported as desired:
https://docs.telerik.com/kendo-ui/framework/drawing/drawing-dom#page-break-limitations
Regards,
Stefan
Progress Telerik
Hi Stefan,
Sorry if I wasn't clear in my last response. The code for positioning the DIVs is in the big chunk of code I posted in my last response. If you copy that whole chunk of code and paste it into the the main.js file you linked over on stackblitz, you can see what I'm talking about. The first chunk of code in my last reply has two columns of text side by side, while the second chunk of code makes those columns of text longer, causing the overflow issue.
I've already read that article as well as the section in the PDF documentation about the limitations of styling elements. The whole reason I posted originally is because none of the points in those articles seems to clearly answer my question of whether or not having two columns of text overflow properly onto the next page is possible, but since I have yet to see an example of this I'm starting to think it really isn't possible. Seems like it should be an easy enough thing to achieve but I guess it isn't. Maybe there's some way to arrange the HTML that I'm not seeing...
Apologies, I assume that there was an issue with StackBlitz when I pasted the finished code. Now I can see the two columns and reproduce the issue.
I forwarded this to the lead developer of the PDF export as I assume this could be connected with the flex styles. Once I have a definitive answer to your questions I will let you know as soon as possible.
Thank you for the patience.
Regards,
Stefan
Progress Telerik
We tested and discussed this with the PDF export developer and indeed exporting vertically aligned elements in this case columns is a limitation of the PDF export functionality.
We do apologize that it took a couple of days to confirm this, but I wanted to make sure before listing it as a limitation.
Regards,
Stefan
Progress Telerik
Thank you for confirming this is a limitation.
For anyone else that may run across this issue in the future- I think what I'll try to do is somehow dynamically compute the height of everything in the document and keep a running tally of the height of each column. When one column receives an element that would cause it to overflow, expand the padding/margins down to fill the remainder of the page, then add the remainder of the content to the a new parent DOM element that will be forced onto the next page. Basically manipulate the DOM content and CSS stylings to force clean breaks in columns, rather than rely solely on the auto-break feature.
Thank you for sharing the approach that you will try to achieve to handle this case.
This will prove helpful to other people from the community when facing this limitation.
Regards,
Stefan
Progress Telerik
Hello Stefan,
We're facing the same problem than explained by John.
Have there been any changes since 2019 regarding this PDF Export trouble ?
Thank you very much
Kind regards
Hello,
The vertical alignment is still a limitation and not fully supported with the PDF export:
Please excuse us for any inconvenience caused by this.