Page 1 of 1

Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 3:06 pm
by til.schniese

We are using the export server to export PDFs from the Scheduler component. Most of the time the schedule is pretty wide (it has tons of date columns). In our use case the pdf should also consist of one page. When now exporting it, the schedule only takes up e.g. 10% of the height of the whole page. This pdf is just unusable, as there is too much white space.
My goal would be to always use 100% of the height and 100% of the width and scale the schedule accordingly. I already tried it by modifying the single page exporter, but when using css scaling, I am also scaling the text, which is getting unreadable, when stretching too much.

Do you guys might have any smart solution to this problem, such that the whole page is getting filled, but the content is still readable?


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 3:07 pm
by mats

Can you please attach some PDFs so we can see the issue. Also your JS configuration would be helpful.


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 3:19 pm
by til.schniese

If you take a look at the unscaled one, it takes up only parts of the height. In the second one I already tried to expand it, but then the text is not readable any more.

I am using the vue component in version 4.2.1


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 4:06 pm
by mats

How about zooming to fit before exporting? Or have user select the time span to print?


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 4:11 pm
by mats

Opened a feature request to look into adding a new option to "trim" the edges of the time axis where there are no events. Would this help in your scenario? https://github.com/bryntum/support/issues/3421


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 4:22 pm
by til.schniese

It was just an example, in a real case the whole timeline would have been filled, so trimming would not help much. Also like they are already able to pick the time span, but its not really convenient to export until you got the right time span, that matches the page


Re: Scale exported pdf to fill up whole page

Posted: Wed Sep 15, 2021 4:53 pm
by mats

And how would it look ideally? Do you want to split it on multiple pages horizontally, vertically?


Re: Scale exported pdf to fill up whole page

Posted: Thu Feb 10, 2022 11:40 am
by til.schniese

I still did not find a solution for this problem. The issue is that the final pdf will only be scaled by one axis, like I described earlier. So when having many date columns, it will be scaled by width, but not by height, and so there is much white space at the bottom. Can we somehow scale it to always fill up the whole page? I attached an ideal version now, of how this could look like.


Re: Scale exported pdf to fill up whole page

Posted: Fri Feb 11, 2022 11:15 am
by Maxim Gorkovsky

Hello.
If I understood your problem correctly, you want exported PDF to be sized according to the content. Is that right? Export server supports that, but export feature does not. Here is a small code snippet that extends SinglePageExporter and uses custom paper format without any scaling. You can try it on our default scheduler export demo to see it in action:

class MySinglePageExporter extends SinglePageExporter {
    static get $name() {
        return 'MySinglePageExporter';
    }

    static get type() {
        return 'mysinglepage';
    }

    async export(config) {
        const result = await super.export(config);

        // Use custom paper format `width*height` to make export server use specific page size
        config.paperFormat = `${this.exportMeta.totalWidth}*${this.exportMeta.totalHeight}`;

        return result;
    }

    pageTpl(data) {
        const
            {
                title,
                header,
                footer,
                styles,
                htmlClasses,
                bodyStyle,
                bodyClasses = [],
                html
            } = data;

        bodyClasses.push(`b-${this.constructor.type}`);

        // Other classes needed on outer element.
        // TODO: use the new static Widget.outerCls property when merged with master
        if (DomHelper.scrollBarWidth) {
            bodyClasses.push('b-visible-scrollbar');
        }
        else {
            bodyClasses.push('b-overlay-scrollbar');
        }
        if (BrowserHelper.isChrome) {
            bodyClasses.push('b-chrome');
        }
        else if (BrowserHelper.isSafari) {
            bodyClasses.push('b-safari');
        }
        else if (BrowserHelper.isFirefox) {
            bodyClasses.push('b-firefox');
        }

        // Total height and width are not provided to the pageTpl function, we have to pull them from the style tag
        const
            styleIndex  = styles.length - (BrowserHelper.isIE11 ? 2 : 1),
            targetStyle = styles[styleIndex],
            totalHeight = targetStyle.match(/height: (\d+)/)[1],
            totalWidth  = targetStyle.match(/width: (\d+)/)[1];

        // Disable scaling style
        styles[styleIndex] = targetStyle.replace('.b-export-content', '#disabled');

        // Put height and width to the instance
        Object.assign(this.exportMeta, {
            totalHeight,
            totalWidth
        });

        return TemplateHelper.tpl`
            <!DOCTYPE html>
            <html class="${htmlClasses}" style="width: ${totalWidth}px; height: ${totalHeight}px;">
                <head>
                    <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
                    <title>${title}</title>
                    ${styles.join('')}
                </head>
                <body class="b-export ${bodyClasses.join(' ')}" style="width: ${totalWidth}px; height: ${totalHeight}px; ${bodyStyle}">
                    <div class="b-export-content">
                        ${header && `<div class="b-export-header" style="width: 100%">${header}</div>`}
                        <div class="b-export-body"><div class="b-export-viewport">${html}</div></div>
                        ${footer && `<div class="b-export-footer" style="width: 100%">${footer}</div>`}
                    </div>
                </body>
            </html>`;
    }
}

new Scheduler({
  features : {
    pdfExport : {
      exporters : [MySinglePageExporter],
      exporterType : 'mysinglepage'
    }
  }
})

For resulting PDF see the attachment


Re: Scale exported pdf to fill up whole page

Posted: Fri Feb 11, 2022 11:58 am
by til.schniese

Thank you for your proposal, we will evaluate, whether this is suitable in our use case