微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将组件反应为 PDF

如何解决将组件反应为 PDF

我正在开发一项功能,该功能将允许用户执行其管道的最后阶段并从中获得精美的 PDF。

我的服务器和客户端都运行良好。我一直无法完成的是将整个文档转换为 pdf。它只捕获了一小部分。

我不需要多个页面,虽然那会很好。无论渲染多长时间,我只想捕捉所有内容。可能有 100 个项目,例如图像和旁边的复选框。我需要一份完整的 pdf 文件,目前我只能得到其中一小部分的快照。

我尝试使用高度选项和各种包,但绝对没有运气。

我将提供 renderSimpleForm 最终在浏览器上的外观。以及它以 PDF 格式显示内容


代码图片


import { jsPDF } from "jspdf";
import * as htmlToImage from 'html-to-image';

        const handleSubmit = () => {
            // //Before sending the action show in progress text and disable button
            setPdf({inProgress: true})

            //Creating the pdf blob
            htmlToImage.toPng(document.getElementById('simpleForm'))
            .then(function (dataUrl) {
              var link = document.createElement('a');
              link.download = 'my-image-name.jpeg';
              const pdf = new jsPDF('p','mm','a4');
              const imgProps= pdf.getimageProperties(dataUrl);
              pdf.addImage(dataUrl,'PNG',0);
              //Send action to server
              ClassInstancesActions.StorePassportPDFTodisk(pdf.output('blob'),productID)
            });
        }

        return (
            <div id="simpleForm" style={{ height: '9999px !important',width: '9999px !important' }}>
                {renderSimpleForm()}
                {showError()}
                {renderSubmitCancel(disableSubmit)}
            </div>
        );
    };
这是我的SUMIT按钮的输出

PDF how it comes out

这就是它在浏览器上的样子

How the Browser Looks with the submit button and items to convert to PDF

解决方法

好的,一段时间后我有一个解决方案可以满足我的需求:

  1. 指向 React 组件中的一个 div,然后将其 pdf 化
  2. 保留样式

和额外的:

  1. 能够以编程方式自定义和控制数据库中的元数据
  2. 定制是添加页眉、页脚、页码、首页,我可以在技术上控制每一页

我使用了 https://www.npmjs.com/package/@progress/kendo-react-pdf

我使用了它的 savePDF 函数,它允许我也有一个模板创建类型的功能,因为它是免费的,并且作为一个 prop 在你将在代码中看到的 options 参数中传递。

还有一个 css 选择器,它只针对已传递的 PDF 化 div,无需指定要显示的内容和不显示的内容,因此您可以在 PDF 完全从这里出来之前实际操作它。

>

在视频演示中,您会看到我有一个超过 40 页的 MASSIVE div! 保留了我的材料和 css 样式,我可以随意添加任何我想要的。 我什至加了水印!

希望这对人们有所帮助!

enter image description here

//component that has the div i need pdf'ed
//

var reactToPdfUtils = require('../../../../../reactToPdf.js');

    const handleSave = (sourceElement) => {
        console.log('handleSave in SFV!');
        reactToPdfUtils.useSavePDFNOW(pdfProps,cb,sourceElement)
        function cb(sendDataContent){   
            console.log(sendDataContent)
        }
    };
    
//////////////////////////////////////////////////////////////////////////////////////////////



//reactToPdf.js      file that houses the library function I manipulate to get the result


import React,{ useEffect } from 'react';
import { savePDF } from '@progress/kendo-react-pdf';
import { drawDOM,exportPDF } from '@progress/kendo-drawing';

export const useSavePDFNOW = (pdfProps,sourceElement) => {
    //pdfprops i pass in from meta data in my mongoDB,//I made a cb to let me know when the funtion is done
    //I also do elaborate checking here myself for example
    //to make sure there is only one div that that id 
   
        //create a template
        //this function is declared then passed in later to savePDF,//the magic in the library allows    you to manipulate each page if you wanted. You can do some         //cool stuff here.
 try {
        const onEveryPage = (props) => {
            if (hasAfirstPage) {
                if (props.pageNum === 1) {
                    document.querySelectorAll('#toPDF')[0].style.cssText = 'margin-top: -188.333px;height:100%;';
                    // document.querySelectorAll('kendo-pdf-page')[0].style.cssText = '';
                    return <Fragment></Fragment>;
                } else {
                    return (
                        <div style={{ zIndex: '-999999',justifyContent: 'center',display: 'flex' }}>
                            <div id='header' style={{ textAlign: 'center',fontSize: headerFontToUse + 'px',backgroundRepeat: 'no-repeat',backgroundSize: '100%',backgroundColor: 'transparent',height: headerHeightToUse,width: headerWidthToUse,backgroundImage: `url(${headerSrcToUse})`,position: 'absolute',top: 10 }}>
                                {headerTextToUse}
                            </div>
                            <div id='watermarkImage' style={{ backgroundRepeat: 'no-repeat',height: waterMarkHeightToUse,opacity: 0.5 /* Firefox,Chrome,Safari,Opera,IE >= 9 (preview) */,backgroundImage: `url(${waterMarkSrcToUse})`,bottom: -90,left: 300 }}></div>
                            <div id='pageNums' style={{ position: 'absolute',bottom: 0,right: '10px' }}>
                                Page {props.pageNum} of {props.totalPages}
                            </div>
                            <h6 id='footer' style={{ fontSize: footerFontToUse + 'px',margin: '6 auto' }}>
                                {footerTextToUse}
                            </h6>
                        </div>
                    );
                }
            } else {
                return (
                    <div style={{ zIndex: '-999999',display: 'flex' }}>
                        <div id='header' style={{ textAlign: 'center',top: 10 }}>
                            {headerTextToUse}
                        </div>
                        <div id='watermarkImage' style={{ backgroundRepeat: 'no-repeat',left: 300 }}></div>
                        <div id='pageNums' style={{ position: 'absolute',right: '10px' }}>
                            Page {props.pageNum} of {props.totalPages}
                        </div>
                        <h6 id='footer' style={{ fontSize: footerFontToUse + 'px',margin: '6 auto' }}>
                            {footerTextToUse}
                        </h6>
                    </div>
                );
            }
        };
        //MaterialUI font fixing may have to do this elsewhere too specific
        parentWrapper.querySelectorAll('[class*=MuiTypography],[class*=Text],[class*=formControl]').forEach(function (el,i) {
            el.setAttribute('style','color: black; overflow: visible');
        });

        //save pdf on client side,send blob to dev to figure out what he or she wants to do with it
        let pdfBlob;
        savePDF(
            parentWrapper,{
                pageTemplate: onEveryPage,paperSize: 'a4',fileName: 'Testing',keepTogether: '.menu',scale: 0.6,title: 'Ametek/Powervar Passport',margin: { top: marginTopToUse,bottom: marginBottomToUse }
            },() => {
                // Server side rendering tested comes out exactly the same so long as the props match
                drawDOM(parentWrapper,{ pageTemplate: onEveryPage,paperSize: 'A4',margin: { top: 180,bottom: 10 } })
                    .then((group) => {
                        return exportPDF(group);
                    })
                    .then((dataUri) => {
                        // Send action to database
                        pdfBlob = dataUri.split(';base64,')[1];
                        ClassInstancesActions.StorePassportPDFToDisk(pdfBlob,'testing');
                        cb(pdfBlob);
                        parentWrapper.remove();
                    });
            }
        );
    } catch (error) {
        console.log(error);
    }
};
//This is in a style sheet
//i have a div within the div I pdf with an id of #divToDisableInteraction
//As long as there in there you can do any css magic to your pdf document here
//I tested this to high heaven you can get most things done here
//including adding an image url


kendo-pdf-document #divToDisableInteraction {
    visibility: hidden;
  }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?