Mali tablolar, hesap bilgileri veya yalnızca tek bir dosyada paylaşılması gereken önemli bilgiler gibi çeşitli nedenlerle web uygulamanızın kullanıcılarına bir PDF belgesi sağlamanız gerekebilir.
Bu makalede, neden istemci tarafında PDF oluşturmayı düşünmeniz gerektiğini ve bu işlevi web'inize veya daha spesifik olarak React uygulamasına nasıl ekleyebileceğinizi açıklayacağım.
Baştan itibaren neler olup bittiğine dair iyi bir genel bakışa sahip olmaktan hoşlandığım için, devam etmeden önce uygulamanın canlı demosunu ve kaynak kodunu görebilirsiniz:
Canlı demo: https://pixochi.github.io/pdf-from-images-react-app/
Kaynak kodu: https://github.com/pixochi/pdf-from-images-react-app
1. Neden İstemci Tarafında / FrontEnd
Uygulamanız henüz kullanmıyorsa herhangi bir sunucu kurmanıza ve bakımını yapmanıza gerek yoktur. Sunucu (lar) ınız daha az kaynak kullanacak çünkü tüm işi tarayıcı yapıyor. Bu, araçlarınıza bağlı olsa da, mevcut tüm ön uç stil çerçevenizden yararlanabilirsiniz.2. Hangi JS kitaplığı kullanmalıyız?
Ön uçta PDF belgeleri oluşturmak için kullanabileceğiniz 3 popüler JavaScript kitaplığı vardır.
jsPDF PDFKit pdfmakeBiz Neden jsPDF'yi Tercih Ettik
Bu proje için şu nedenlerle jsPDF'yi seçtik :
En yüksek GitHub yıldızı sayısı (20.3K) Vade (2014'te piyasaya sürüldü) yani kararlı bir sürüm En küçük boyut (PDFKit'ten% 87 daha küçük ve pdfmake'den% 460 daha küçük) Local TypeScript desteği Anlaşılır Döküman Desteği3. React uygulamasını oluşturalım
İlk kurulum
Basit tutmak için, uygulamayı Create React App ile kuracağız . Projeyi başlatmak için terminalinizde tek bir komut çalıştırın:
npx create-react-app pdf-from-images-react-app --template typescriptKurulum tamamlandığında jspdf paketi ekleyelim:
npm install jspdfArdından React uygulamasını şu şekilde başlatın:
npm startUI iskeleti
İşlevselliği uygulamadan önce, uygulama kullanıcı arayüzünü hazırlayacağız.
Tüm içeriğini App.tsx aşağıdaki kodla değiştirebilirsiniz:
import React from "react"; import "./App.css"; // Placeholder for future app functionality, // the actual functionality will be implemented later. const NO_OP = () => {}; function App() { // State for uploaded images const [uploadedImages, setUploadedImages] = React.useState<any>([]); return ( <> <h1>Convert images to PDFs</h1> {/* Overview of uploaded images */} <div className="images-container"> {uploadedImages.length > 0 ? ( uploadedImages.map((image: any) => ( <img key={image.name} src={image.src} className="uploaded-image" /> )) ) : ( <p>Upload some images...</p> )} </div> {/* Buttons for uploading images and generating a PDF */} <div className="buttons-container"> {/* Uploads images */} <label htmlFor="file-input"> <span className="button">Upload images</span> <input id="file-input" type="file" accept="image/*" onChange={NO_OP} // Native file input is hidden only for styling purposes style={{ display: "none" }} multiple /> </label> {/* Generates PDF */} <button onClick={NO_OP} className="button" disabled={uploadedImages.length === 0} > Generate PDF </button> </div> </> ); } export default App;Yukarıdaki kodda, birkaç className s fark edebilirsiniz - bunlar, uygulamanın minimum stil ayarlamaları içindir. Aşağıdaki CSS kurallarını içeren tüm ' className kaynaklıdır; App.css dosyamınızı açıyoruz ve aşağıdaki kodları ekliyoruz.
İçerik yerini ile App.tsxve App.css, uygulamamızda başarılı bir şekilde uygulandığından emin olmak için uygulama tarayıcınızda bu göz atmalısınız.
Cihazınızdan resim yükleme
Bir PDF oluşturmadan önce, görüntüleri cihazınızdan okumanız gerekir. App.tsx zaten dosya input seçmek için bir dosya öğesi içeriyor , şimdi seçili görüntüleri uygulama durumuna getirmemiz gerekiyor.
handleImageUpload Yüklenen görüntüleri işleyen ve durumu güncelleyen işleve dikkat edin :
import React, { ChangeEventHandler } from "react"; import "./App.css"; // Placeholder for future app functionality, // the actual functionality will be implemented later. const NO_OP = () => {}; // New class with additional fields for Image class CustomImage extends Image { constructor(public mimeType: string) { super(); } // `imageType` is a required input for generating a PDF for an image. get imageType(): string { return this.mimeType.split("/")[1]; } } // Each image is loaded and an object URL is created. const fileToImageURL = (file: File): Promise<CustomImage> => { return new Promise((resolve, reject) => { const image = new CustomImage(file.type); image.onload = () => { resolve(image); }; image.onerror = () => { reject(new Error("Failed to convert File to Image")); }; image.src = URL.createObjectURL(file); }); }; function App() { // State for uploaded images const [uploadedImages, setUploadedImages] = React.useState<CustomImage[]>([]); const handleImageUpload = React.useCallback< ChangeEventHandler<HTMLInputElement> >( (event) => { // `event.target.files` is of type `FileList`, // we convert it to Array for easier manipulation. const fileList = event.target.files; const fileArray = fileList ? Array.from(fileList) : []; // Uploaded images are read and the app state is updated. const fileToImagePromises = fileArray.map(fileToImageURL); Promise.all(fileToImagePromises).then(setUploadedImages); }, [setUploadedImages] ); return ( <> <h1>Convert images to PDFs</h1> {/* Overview of uploaded images */} <div className="images-container"> {uploadedImages.length > 0 ? ( uploadedImages.map((image) => ( <img key={image.src} src={image.src} className="uploaded-image" /> )) ) : ( <p>Upload some images...</p> )} </div> {/* Buttons for uploading images and generating a PDF */} <div className="buttons-container"> {/* Uploads images */} <label htmlFor="file-input"> <span className="button">Upload images</span> <input id="file-input" type="file" accept="image/*" onChange={handleImageUpload} // Native file input is hidden only for styling purposes style={{ display: "none" }} multiple /> </label> {/* Generates PDF */} <button onClick={NO_OP} className="button" disabled={uploadedImages.length === 0} > Generate PDF </button> </div> </> ); } export default App;En son değişikliklerle, yeşil “Upload Images” düğmesine tıklayabilmeli, resimleri seçebilmeli ve ardından resimler kullanıcı arayüzünde görüntülenmelidir.
Yüklenen görüntülerden bir PDF oluşturma
Son adım, nihayet tüm görüntüleri içeren bir PDF belgesi oluşturmaktır. App.tsx Aşağıdaki değişikliklerle güncellemenizi yaptıktan sonra , React uygulamanız tamamlanır.
Yeni handleGeneratePdfFromImages fonksiyonu, PDF oluşturma ve uygulama temizleme ile ilgilenir. Artık "Generate PDF" düğmesini tıkladığınızda, PDF'niz indirilmeye hazırdır.
Orjinal Makale : https://medium.com/javascript-in-plain-english/generating-pdf-from-images-on-the-client-side-with-react-a971b61de28c
Arkadaşlar umarım yardımcı olmuştur.