skip to Main Content

I created an app using react.js and GraphSQL, in my application there is a page that displays some details that I want to print as a PDF when a button is clicked.

The data that should be in the PDF is from GraphSQL, for that I used html2canvas and jsPDF. It is somewhat correct on Windows (13" screen) but on mac (16" screen) it is broken.

Here is the PDF generated as displayed on a Mac:
enter image description here

And this is the data that I want to print (only the first part is on Mac):

enter image description here

Code:

import jsPDF from 'jspdf';
import html2canvas from 'html2canvas';
const PrintDocument =() => {
  const input = document.getElementById('divToPrint');
  html2canvas(input)
    .then((canvas) => {
      const imgData = canvas.toDataURL('image/png');
      const pdf = new jsPDF();
      pdf.addImage(imgData, 'JPEG', 0, 0);
      // pdf.output('dataurlnewwindow');
      pdf.save("download.pdf");
    })
  ;
}
export default function OrderDetails(props) {
    let  id  = props.match.params.id;
   id = "gid://shopify/Order/" + id ;
  const { loading, error, data } = useQuery(GET_Single_Orders, {
    variables:  {id}
    ,
  });
  
  if (loading) return <h4>読み込み中...</h4>;
  if (error) return `Error! ${error}`;

  return( 
  <div >




   <div id="divToPrint" >
   <Container>
    <Row>
    <Col>
    <h4> 発送の詳細 </h4>
   
    <div key={data?.Order?.id}>
    <p> <span className="user"> 住所 : </span>{data?.Order?.shippingAddress?. address1 || "指定されていない" } </p>
    <p> <span className="user"> 住所 2 : </span>{data?.Order?.shippingAddress?.address2|| "指定されていない" } </p>
    <p> <span className="user"> 市 : </span>{data?.Order?.shippingAddress?.city|| "指定されていない" } </p>
    <p><span className="user"> 会社 : </span>{data?.Order?.shippingAddress?.company || "指定されていない"  } </p>
    <p><span className="user"> 国 : </span>{data?.Order?.shippingAddress?.country || "指定されていない" } </p>
    <p><span className="user"> 国コード : </span>{data?.Order?.shippingAddress?.countryCode || "指定されていない" } </p>
    <p><span className="user"> ファーストネーム : </span>{data?.Order?.shippingAddress?.firstName || "指定されていない" } </p>
    <p><span className="user"> 苗字 : </span>{data?.Order?.shippingAddress?.lastName || "指定されていない" } </p>
    <p><span className="user"> 電話番号 : </span>{data?.Order?.shippingAddress?.phone || "指定されていない" }</p>
    <p><span className="user"> 州 : </span>{data?.Order?.shippingAddress?.   province || "指定されていない"  } , {data?.Order?.shippingAddress?.provinceCode|| "指定されていない" } </p>
   
                      
                     
    </div>
    </Col>
   // the rest of the code

   </Container>
   </div>
<div>
<Button variant="secondary" onClick={PrintDocument} >印刷</Button>
 </div>

 </div>
 )}

UPDATE :
i was able to make it work using this library : react-to-pdf
but in production i cannot see anything , basically a blank page

in development :
enter image description here

in production :

enter image description here

2

Answers


  1. Chosen as BEST ANSWER

    Itge only solution that worked in my case is totally switching to react-to-print package ( https://www.npmjs.com/package/react-to-print)

    No it is perfect on mac and Windows and in dev and


  2. For the truncated/trimmed pdf using jsPDF, try specifying the width and height in this line

    pdf.addImage(imgData, 'JPEG', 0, 0);
    // change it to
    pdf.addImage(imgData, 'JPEG', 0, 0, width, height);
    

    these width and height could be extracted from the canvas.

    And, scroll to the top of the page before capturing the image with html2canvas

    window.scrollTo(0,0)
    

    So, as a final result you should have something like this:

    html2canvas((content), {scrollY: -window.scrollY, scrollX: -window.scrollX}).then(function (canvas) {
            var img = canvas.toDataURL("image/png");
            var doc = new jsPDF({
                unit:'px', 
                format:'a4'
            });
        // dynamic width and height
            var width = doc.internal.pageSize.getWidth();
            var height = doc.internal.pageSize.getHeight();
    
            let widthRatio = width / canvas.width;
            let heightRatio = height / canvas.height;
    
            let ratio = widthRatio > heightRatio ? heightRatio : widthRatio
    
             doc.addImage(imgData, "PNG", 0, 0, canvas.width * ratio, canvas.height * ratio);
            doc.save('test.pdf');
        });
     
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search