跳過到頁腳內容
NODE 說明

dropzone npm(開發者的使用方法)

檔案上傳是網頁應用程式中的常見功能,並且令其使用者友好對於良好的使用者體驗至關重要。 一個簡化此流程的熱門庫是Dropzone.js。 When combined with React, Dropzone can be a powerful tool for implementing drag-and-drop file uploads. react-dropzone完美且無縫地整合,開發工作量最小。 本文將指導您使用react-dropzone套件將Dropzone與React應用程式整合,該包是Dropzone.js庫的優秀包裝器。

在本文中,我們還將了解IronPDF NPM套件來生成、編輯和管理PDF文件。

為什麼要在React中使用Dropzone?

Dropzone提供了多種功能,使檔案上傳無縫銜接:

1. 拖放介面

允許使用者拖放文件以啟用文件選擇,並以程式方式添加文件對話框。

2. 預覽

顯示從丟下的文件中獲得的默認影像縮圖預覽,增強了UI的可讀性。

3. 多文件上傳

支持一次上傳多個文件。

4. 可自定義

高度可自定義,具有多種選項和回調。 您可以自定義文件對話框打開或文件選擇對話框。

5. 大文件分塊上傳

使用分塊上傳上傳大文件。

6. 處理事件

可以處理文件對話框取消回調和瀏覽器影像縮放事件。

設置React應用程式

在整合Dropzone之前,確保您有一個設置好的React應用程式。如果您沒有,可以使用Create React App創建一個新的React專案:

npx create-react-app dropzone-demo
cd dropzone-demo
npx create-react-app dropzone-demo
cd dropzone-demo
SHELL

安裝react-dropzone

要在React專案中使用Dropzone,您需要安裝react-dropzone套件

npm install react-dropzone
# or
yarn add react-dropzone
npm install react-dropzone
# or
yarn add react-dropzone
SHELL

react-dropzone的基本用法

以下是React組件中使用react-dropzone的簡單示例:

import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';

// DropzoneComponent is a React component demonstrating basic usage of react-dropzone
const DropzoneComponent = () => {
  // Callback to handle file drops
  const onDrop = useCallback((acceptedFiles) => {
    console.log(acceptedFiles); // Log the accepted files
  }, []);

  // Extracted properties from useDropzone hook
  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} style={dropzoneStyle}>
      <input {...getInputProps()} />
      {
        isDragActive ? 
          <p>Drop the files here ...</p> : 
          <p>Drag 'n' drop some files here, or click to select files</p>
      }
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone';

// DropzoneComponent is a React component demonstrating basic usage of react-dropzone
const DropzoneComponent = () => {
  // Callback to handle file drops
  const onDrop = useCallback((acceptedFiles) => {
    console.log(acceptedFiles); // Log the accepted files
  }, []);

  // Extracted properties from useDropzone hook
  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  return (
    <div {...getRootProps()} style={dropzoneStyle}>
      <input {...getInputProps()} />
      {
        isDragActive ? 
          <p>Drop the files here ...</p> : 
          <p>Drag 'n' drop some files here, or click to select files</p>
      }
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
JAVASCRIPT

處理文件上傳

當文件被丟下或選擇時,onDrop回調會接收到一個接受的文件陣列。 接著您可以處理這些文件,例如將它們上傳到服務器。 以下是如何擴展onDrop回調以使用汲取上傳文件的方法:

// onDrop callback to handle file uploads
const onDrop = useCallback((acceptedFiles) => {
  const formData = new FormData();
  // Append each file to the formData
  acceptedFiles.forEach((file) => {
    formData.append('files', file);
  });

  // Send a POST request to upload the files
  fetch('https://your-upload-endpoint', {
    method: 'POST',
    body: formData,
  })
  .then(response => response.json()) // Parse the JSON from the response
  .then(data => console.log(data)) // Log the response data
  .catch(error => console.error('Error:', error)); // Handle errors
}, []);
// onDrop callback to handle file uploads
const onDrop = useCallback((acceptedFiles) => {
  const formData = new FormData();
  // Append each file to the formData
  acceptedFiles.forEach((file) => {
    formData.append('files', file);
  });

  // Send a POST request to upload the files
  fetch('https://your-upload-endpoint', {
    method: 'POST',
    body: formData,
  })
  .then(response => response.json()) // Parse the JSON from the response
  .then(data => console.log(data)) // Log the response data
  .catch(error => console.error('Error:', error)); // Handle errors
}, []);
JAVASCRIPT

顯示預覽

您還可以顯示已上傳文件的預覽。 以下是一個實例,展示如何做到這一點:

import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);

  // onDrop callback to handle file drops and generate previews
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(acceptedFiles.map(file => Object.assign(file, {
      preview: URL.createObjectURL(file)
    })));
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  // Generate thumbnails for each file
  const thumbs = files.map(file => (
    <div key={file.name}>
      <img
        src={file.preview}
        style={{ width: '100px', height: '100px' }}
        alt={file.name}
      />
    </div>
  ));

  return (
    <div>
      <div {...getRootProps()} style={dropzoneStyle}>
        <input {...getInputProps()} />
        {
          isDragActive ? 
            <p>Drop the files here ...</p> : 
            <p>Drag 'n' drop some files here, or click to select files</p>
        }
      </div>
      <div>
        {thumbs}
      </div>
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';

const DropzoneComponent = () => {
  const [files, setFiles] = useState([]);

  // onDrop callback to handle file drops and generate previews
  const onDrop = useCallback((acceptedFiles) => {
    setFiles(acceptedFiles.map(file => Object.assign(file, {
      preview: URL.createObjectURL(file)
    })));
  }, []);

  const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });

  // Generate thumbnails for each file
  const thumbs = files.map(file => (
    <div key={file.name}>
      <img
        src={file.preview}
        style={{ width: '100px', height: '100px' }}
        alt={file.name}
      />
    </div>
  ));

  return (
    <div>
      <div {...getRootProps()} style={dropzoneStyle}>
        <input {...getInputProps()} />
        {
          isDragActive ? 
            <p>Drop the files here ...</p> : 
            <p>Drag 'n' drop some files here, or click to select files</p>
        }
      </div>
      <div>
        {thumbs}
      </div>
    </div>
  );
};

// Styles for the dropzone area
const dropzoneStyle = {
  border: '2px dashed #0087F7',
  borderRadius: '5px',
  padding: '20px',
  textAlign: 'center',
  cursor: 'pointer'
};

export default DropzoneComponent;
JAVASCRIPT

清理

撤銷對象URL以避免內存洩漏是必不可少的。 您可以通過使用useEffect鉤子來實現這一點:

import { useEffect } from 'react';

// useEffect to clean up object URLs to prevent memory leaks
useEffect(() => {
  // Revoke the data URIs
  return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
import { useEffect } from 'react';

// useEffect to clean up object URLs to prevent memory leaks
useEffect(() => {
  // Revoke the data URIs
  return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
JAVASCRIPT

介紹IronPDF

IronPDF是一個強大的npm套件,旨在促進Node.js應用程式中的PDF生成。 It allows you to create PDF documents from HTML content, URLs, or even existing PDF files. 無論您是在生成發票、報告還是其他類型的文件,IronPDF都會通過其直觀的API和強大的功能集來簡化此過程。

IronPDF的主要特性包括

1. HTML到PDF轉換

輕鬆將 HTML 內容轉換為 PDF 文檔。 此功能特別適合從網頁內容生成動態 PDF。

2. URL到PDF轉換

直接從URL生成PDF。 這允許您捕獲網頁內容並將其程式化地另存為PDF文件。

3. PDF操作

輕鬆合併、拆分和操作現有的 PDF 文檔。 IronPDF提供了操作PDF文件的功能,例如追加頁面、拆分文件等。

4. PDF安全

通過設置密碼或應用數字簽名來保護您的 PDF 文件。 IronPDF 提供選項以保護您的機密文件免遭未授權訪問。

5. 高品質輸出

生成的 PDF 文檔具有精確的文字、圖片和格式渲染,具有高品質。 IronPDF 確保您生成的 PDF 保持對原始內容的保真度。

6. 跨平台兼容性

IronPDF與包括Windows、Linux和macOS在內的多個平台兼容,適合各種開發環境。

7. 簡單整合

輕鬆將 IronPDF 整合到您的 Node.js 應用中,使用其 npm 包。 API 文檔完善,使其易於將 PDF 生成功能納入您的項目。

無論您是在構建網頁應用程式、服務器端腳本還是命令行工具,IronPDF都會授予您創建專業級PDF文件的能力,高效且可靠。

使用IronPDF生成PDF文件並使用Dropzone NPM套件

安裝依賴項:首先,使用以下命令創建一個新的Next.js專案(如果您還沒有),請參考頁面

npx create-next-app@latest demo-dropzone-ironpdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
npx create-next-app@latest demo-dropzone-ironpdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
SHELL

接下來,導航至您的項目目錄:

cd demo-dropzone-ironpdf
cd demo-dropzone-ironpdf
SHELL

安裝所需的包:

npm install @ironsoftware/ironpdf
npm install react-dropzone
npm install @ironsoftware/ironpdf
npm install react-dropzone
SHELL

創建PDF:現在,讓我們創建一個使用IronPDF生成PDF的簡單示例。 在您的Next.js組件(e.g., pages/index.tsx)中添加以下代碼:

import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useState } from "react";
import DropzoneComponent from "../components/mydropzone";

export default function Home() {
    const [textInput, setTextInput] = useState('');

    // Function to display different types of toast messages
    const notify = () => {
        toast.success("Success! This is a success message.", {
            position: "top-right"
        });
        toast.info("Information message", {
            position: "bottom-left"
        });
        toast.warn("Warning message", {
            autoClose: 5000
        });
        toast.error("Error message", {
            className: 'custom-toast',
            style: { background: 'red', color: 'white' }
        });
    };

    // Function to generate and download a PDF
    const generatePdf = async () => {
        try {
            const response = await fetch('/api/pdf?url=' + textInput);
            const blob = await response.blob();
            const url = window.URL.createObjectURL(new Blob([blob]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'awesomeIron.pdf');
            document.body.appendChild(link);
            link.click(); // Trigger the download
            link.parentNode.removeChild(link); // Remove the link
        } catch (error) {
            console.error('Error generating PDF:', error);
        }
    };

    // Handle changes in the text input field
    const handleChange = (event) => {
        setTextInput(event.target.value);
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Generate PDF Using IronPDF</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main>
                <h1>Demo Drop Zone and Generate PDF Using IronPDF</h1>
                <DropzoneComponent />
                <p>
                    <span>Enter Url To Convert to PDF:</span>{" "}
                </p>
                <button style={{ margin: 20, padding: 5 }} onClick={generatePdf}>Generate PDF</button>
            </main>
            <style jsx>{`
                main {
                    padding: 5rem 0;
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                }
                footer {
                    width: 100%;
                    height: 100px;
                    border-top: 1px solid #eaeaea;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                footer img {
                    margin-left: 0.5rem;
                }
                footer a {
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    text-decoration: none;
                    color: inherit;
                }
                code {
                    background: #fafafa;
                    border-radius: 5px;
                    padding: 0.75rem;
                    font-size: 1.1rem;
                    font-family: Menlo,
                    Monaco,
                    Lucida Console,
                    Liberation Mono,
                    DejaVu Sans Mono,
                    Bitstream Vera Sans Mono,
                    Courier New,
                    monospace;
                }
            `}</style>
            <style jsx global>{`
                html,
                body {
                    padding: 0;
                    margin: 0;
                    font-family: -apple-system,
                    BlinkMacSystemFont,
                    Segoe UI,
                    Roboto,
                    Oxygen,
                    Ubuntu,
                    Cantarell,
                    Fira Sans,
                    Droid Sans,
                    Helvetica Neue,
                    sans-serif;
                }
                * {
                    box-sizing: border-box;
                }
            `}</style>
        </div>
    );
}
import Head from 'next/head';
import styles from '../styles/Home.module.css';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import { useState } from "react";
import DropzoneComponent from "../components/mydropzone";

export default function Home() {
    const [textInput, setTextInput] = useState('');

    // Function to display different types of toast messages
    const notify = () => {
        toast.success("Success! This is a success message.", {
            position: "top-right"
        });
        toast.info("Information message", {
            position: "bottom-left"
        });
        toast.warn("Warning message", {
            autoClose: 5000
        });
        toast.error("Error message", {
            className: 'custom-toast',
            style: { background: 'red', color: 'white' }
        });
    };

    // Function to generate and download a PDF
    const generatePdf = async () => {
        try {
            const response = await fetch('/api/pdf?url=' + textInput);
            const blob = await response.blob();
            const url = window.URL.createObjectURL(new Blob([blob]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', 'awesomeIron.pdf');
            document.body.appendChild(link);
            link.click(); // Trigger the download
            link.parentNode.removeChild(link); // Remove the link
        } catch (error) {
            console.error('Error generating PDF:', error);
        }
    };

    // Handle changes in the text input field
    const handleChange = (event) => {
        setTextInput(event.target.value);
    }

    return (
        <div className={styles.container}>
            <Head>
                <title>Generate PDF Using IronPDF</title>
                <link rel="icon" href="/favicon.ico" />
            </Head>
            <main>
                <h1>Demo Drop Zone and Generate PDF Using IronPDF</h1>
                <DropzoneComponent />
                <p>
                    <span>Enter Url To Convert to PDF:</span>{" "}
                </p>
                <button style={{ margin: 20, padding: 5 }} onClick={generatePdf}>Generate PDF</button>
            </main>
            <style jsx>{`
                main {
                    padding: 5rem 0;
                    flex: 1;
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                }
                footer {
                    width: 100%;
                    height: 100px;
                    border-top: 1px solid #eaeaea;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                }
                footer img {
                    margin-left: 0.5rem;
                }
                footer a {
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    text-decoration: none;
                    color: inherit;
                }
                code {
                    background: #fafafa;
                    border-radius: 5px;
                    padding: 0.75rem;
                    font-size: 1.1rem;
                    font-family: Menlo,
                    Monaco,
                    Lucida Console,
                    Liberation Mono,
                    DejaVu Sans Mono,
                    Bitstream Vera Sans Mono,
                    Courier New,
                    monospace;
                }
            `}</style>
            <style jsx global>{`
                html,
                body {
                    padding: 0;
                    margin: 0;
                    font-family: -apple-system,
                    BlinkMacSystemFont,
                    Segoe UI,
                    Roboto,
                    Oxygen,
                    Ubuntu,
                    Cantarell,
                    Fira Sans,
                    Droid Sans,
                    Helvetica Neue,
                    sans-serif;
                }
                * {
                    box-sizing: border-box;
                }
            `}</style>
        </div>
    );
}
JAVASCRIPT

既然IronPDF只能在Node上運行,那就為生成PDF的應用添加API。

pages/api文件夾下創建一個pdf.js文件,並添加以下源代碼:

// pages/api/pdf.js
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";

export default async function handler(req, res) {
    try {
        const url = req.query.url;
        const pdf = await PdfDocument.fromUrl(url);
        const data = await pdf.saveAsBuffer();
        console.log('PDF data:', data);

        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', 'attachment; filename=awesomeIron.pdf');
        res.send(data);
    } catch (error) {
        console.error('Error generating PDF:', error);
        res.status(500).end();
    }
}
// pages/api/pdf.js
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";

export default async function handler(req, res) {
    try {
        const url = req.query.url;
        const pdf = await PdfDocument.fromUrl(url);
        const data = await pdf.saveAsBuffer();
        console.log('PDF data:', data);

        res.setHeader('Content-Type', 'application/pdf');
        res.setHeader('Content-Disposition', 'attachment; filename=awesomeIron.pdf');
        res.send(data);
    } catch (error) {
        console.error('Error generating PDF:', error);
        res.status(500).end();
    }
}
JAVASCRIPT

注意:在上述代碼中,請確保添加您自己的許可證密鑰。

運行您的應用:啟動您的Next.js應用:

npm run dev
# or
yarn dev
npm run dev
# or
yarn dev
SHELL

現在,輸入網站URL以生成PDF並單擊“生成PDF”。 將下載名為awesomeIron.pdf的文件,如下所示。

現在點擊Dropzone並選擇下載的文件。這將顯示文件預覽,底部顯示文件名:awesomeIron.pdf

IronPDF 授權

有關許可證詳細信息,請參考IronPDF頁面。

將許可證密鑰放置在應用中,如下所示:

import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
import { IronPdfGlobalConfig, PdfDocument } from "@ironsoftware/ironpdf";

// Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here";
JAVASCRIPT

結論

Integrating Dropzone with React using react-dropzone is a straightforward process that significantly enhances the file upload experience. 具有拖放、文件預覽和廣泛的自定義選項等功能,react-dropzone可以成為您React專案的一個寶貴補充。 開始探索它的功能並根據您的應用需求進行定制!

IronPDF,另一方面,是一個多功能的PDF生成和操作庫,易於整合到應用程式中。 IronPDF offers thorough documentation and code examples to help developers to get started.

通過遵循本文中概述的步驟,您可以在React應用程式中創建一個強大的文件上傳組件,還可以將PDF文件生成功能納入現代應用程式。

Darrius Serrant
全棧軟件工程師 (WebOps)

Darrius Serrant 擁有邁阿密大學計算機科學學士學位,目前任職於 Iron Software 的全栈 WebOps 市場營銷工程師。從小就迷上編碼,他認為計算既神秘又可接近,是創意和解決問題的完美媒介。

在 Iron Software,Darrius 喜歡創造新事物,並簡化複雜概念以便於理解。作為我們的駐場開發者之一,他也自願教學生,分享他的專業知識給下一代。

對 Darrius 來說,工作令人滿意因為它被重視且有實際影響。