在实际环境中测试
在生产中测试无水印。
随时随地为您服务。
文件上传是 Web 应用程序中的常见功能,使其对用户友好对于良好的用户体验至关重要。 一种简化此过程的流行库是 Dropzone.js. 结合时 React, Dropzone 可以成为实现拖放文件上传的强大工具。 react-dropzone 可以完美无缝地集成,仅需很少的开发工作。 本文将指导您完成集成 拖放区 与 React 应用程序一起使用 react-dropzone 包,一个围绕 Dropzone.js 库的出色封装。
在本文中,我们还将探讨 IronPDF 用于生成、编辑和管理PDF文档的NPM软件包。
Dropzone 提供使文件上传无缝的各种功能:
允许用户拖放文件以启用文件选择。 以编程方式添加文件对话框。
显示从拖放文件中默认的图像缩略图预览。 显示文件预览有助于提高用户界面的可读性。
支持一次上传多个文件。
高度可定制,具有多种选项和回调。 可以自定义文件对话框打开或文件选择对话框
使用分块上传上传大文件。
可以处理文件对话框取消回调以及浏览器图像调整大小事件。
在集成Dropzone之前,确保您已经设置了一个React应用程序。如果您还没有,可以使用创建一个新的React项目。 创建 React 应用:
npx create-react-app dropzone-demo
cd dropzone-demo
npx create-react-app dropzone-demo
cd dropzone-demo
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npx create-react-app dropzone-demo cd dropzone-demo
要在您的 React 项目中使用 Dropzone,您需要安装 react-dropzone 包:
npm install react-dropzone
or
yarn add react-dropzone
npm install react-dropzone
or
yarn add react-dropzone
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npm install react-dropzone @or yarn add react-dropzone
以下是一个在 React 组件中使用 react-dropzone 的简单示例:
import React, { useCallback } from 'react';
import { useDropzone } from 'react-dropzone'; // import dropzone
const DropzoneComponent = () => {
const onDrop = useCallback((acceptedFiles) => {
console.log(acceptedFiles);
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<div {...getRootProps()} style={dropzoneStyle}>
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
);
};
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'; // import dropzone
const DropzoneComponent = () => {
const onDrop = useCallback((acceptedFiles) => {
console.log(acceptedFiles);
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
return (
<div {...getRootProps()} style={dropzoneStyle}>
{
isDragActive ?
<p>Drop the files here ...</p> :
<p>Drag 'n' drop some files here, or click to select files</p>
}
</div>
);
};
const dropzoneStyle = {
border: '2px dashed #0087F7',
borderRadius: '5px',
padding: '20px',
textAlign: 'center',
cursor: 'pointer'
};
export default DropzoneComponent;
'INSTANT VB TODO TASK: The following line could not be converted:
import React,
If True Then
useCallback
End If
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'from 'react'; import { useDropzone } from 'react-dropzone'; const DropzoneComponent = () => { const onDrop = useCallback((acceptedFiles) => { console.log(acceptedFiles); }, []); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop }); Return(<div {...getRootProps()} style={dropzoneStyle}> { isDragActive ? <p> Drop the files here...</p> : <p> Drag "n"c drop some files here, @or click @to select files</p> } </div>); }; const dropzoneStyle = { border: '2px dashed #0087F7', borderRadius: '5px', padding: '20px', textAlign: 'center', cursor: 'pointer' }; export default DropzoneComponent;
当文件被拖放或选中时,onDrop 回调接收到一个被接受文件的数组。 然后,您可以处理这些文件,例如将它们上传到服务器。 以下是如何扩展 onDrop 回调以使用 fetch 上传文件的方法:
const onDrop = useCallback((acceptedFiles) => {
const formData = new FormData();
acceptedFiles.forEach((file) => {
formData.append('files', file);
});
fetch('https://your-upload-endpoint', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}, []);
const onDrop = useCallback((acceptedFiles) => {
const formData = new FormData();
acceptedFiles.forEach((file) => {
formData.append('files', file);
});
fetch('https://your-upload-endpoint', {
method: 'POST',
body: formData,
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
}, []);
'INSTANT VB TODO TASK: Lambda expressions and anonymous methods are not converted by Instant VB if local variables of the outer method are referenced within the anonymous method:
const onDrop = useCallback((acceptedFiles) =>
If True Then
const formData = New FormData()
'INSTANT VB TODO TASK: Lambda expressions and anonymous methods are not converted by Instant VB if local variables of the outer method are referenced within the anonymous method:
acceptedFiles.forEach((file) =>
If True Then
formData.append( 'files', file);
End If
)
fetch( 'https: method: 'POST', body: formData}).@then(response => response.json()).@then(data => console.log(data)).catch(@error => console.@error('@Error:', @error));
End If
, ())
您还可以显示上传文件的预览。 这是一个如何做到这一点的示例:
import React, { useCallback, useState } from 'react';
import { useDropzone } from 'react-dropzone';
const DropzoneComponent = () => {
const [files, setFiles] = useState([]);
const onDrop = useCallback((acceptedFiles) => {
setFiles(acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
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}>
{
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>
);
};
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([]);
const onDrop = useCallback((acceptedFiles) => {
setFiles(acceptedFiles.map(file => Object.assign(file, {
preview: URL.createObjectURL(file)
})));
}, []);
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
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}>
{
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>
);
};
const dropzoneStyle = {
border: '2px dashed #0087F7',
borderRadius: '5px',
padding: '20px',
textAlign: 'center',
cursor: 'pointer'
};
export default DropzoneComponent;
'INSTANT VB TODO TASK: The following line could not be converted:
import React,
If True Then
useCallback, useState
End If
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'from 'react'; import { useDropzone } from 'react-dropzone'; const DropzoneComponent = () => { const [files, setFiles] = useState([]); const onDrop = useCallback((acceptedFiles) => { setFiles(acceptedFiles.map(file => Object.assign(file, { preview: URL.createObjectURL(file) }))); }, []); const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop }); 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}> { isDragActive ? <p> Drop the files here...</p> : <p> Drag "n"c drop some files here, @or click @to select files</p> } </div> <div> {thumbs} </div> </div>); }; const dropzoneStyle = { border: '2px dashed #0087F7', borderRadius: '5px', padding: '20px', textAlign: 'center', cursor: 'pointer' }; export default DropzoneComponent;
撤销对象 URL 是必不可少的,以避免内存泄漏。 您可以通过使用 useEffect 钩子来实现这一点:
import { useEffect } from 'react';
useEffect(() => {
// Make sure to revoke the data uris to avoid memory leaks
return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
import { useEffect } from 'react';
useEffect(() => {
// Make sure to revoke the data uris to avoid memory leaks
return () => files.forEach(file => URL.revokeObjectURL(file.preview));
}, [files]);
import
If True Then
useEffect
End If
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'from 'react'; useEffect(() => { Return() => files.forEach(file => URL.revokeObjectURL(file.preview)); }, [files]);
IronPDF 是一个功能强大的npm包,旨在促进Node.js应用程序中的PDF生成。 它允许您从中创建PDF文档 HTML 内容, 网址,甚至现有的PDF文件。 无论您是在生成发票、报告还是其他任何类型的文档,IronPDF都通过其直观的功能简化了流程。 应用程序接口 和强大的功能集。
将 HTML 内容轻松转换为 PDF 文档。 此功能特别适用于从网页内容生成动态PDF。
直接从网址生成PDF。 这使您能够通过编程方式捕获网页内容并将其保存为PDF文件。
轻松合并、拆分和操作现有的PDF文档。 IronPDF提供了操作PDF文件的功能,例如添加页面、分割文档等。
通过设置密码或应用数字签名来保护您的PDF文档。 IronPDF 提供选项以保护您的敏感文档免受未经授权的访问。
生成高质量的PDF文档,精确渲染文本、图像和格式。 IronPDF 确保您生成的 PDF 保持与原始内容的一致性。
IronPDF兼容多个平台,包括Windows、Linux和macOS,使其适用于广泛的开发环境。
使用其npm软件包轻松将IronPDF集成到您的Node.js应用程序中。 API 文档详实,使将 PDF 生成功能集成到您的项目中变得简单明了。
无论您是在构建 Web 应用程序、服务器端脚本还是命令行工具, IronPDF 赋予您高效且可靠地创建专业级PDF文档的能力。
安装依赖项:首先,创建一个新的 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"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npx create-@next-app@latest demo-dropzone-ironpdf --use-npm --example "https://github.com/vercel/next-learn/tree/main/basics/learn-starter"
接下来,导航到你的项目目录:
cd demo-dropzone-ironpdf
cd demo-dropzone-ironpdf
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'cd demo-dropzone-ironpdf
安装所需的软件包:
npm install @ironsoftware/ironpdf
npm install react-dropzone
npm install @ironsoftware/ironpdf
npm install react-dropzone
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npm install @ironsoftware/ironpdf npm install react-dropzone
创建PDF:现在,让我们用IronPDF创建一个生成PDF的简单示例。 在您的Next.js组件中 (例如,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('');
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'}
});
};
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();
link.parentNode.removeChild(link);
} catch (error) {
console.error('Error generating PDF:', error);
}
};
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('');
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'}
});
};
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();
link.parentNode.removeChild(link);
} catch (error) {
console.error('Error generating PDF:', error);
}
};
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>
);
}
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'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(''); 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'} }); }; const generatePdf = async() => { try { const response = await fetch('/api/System.Nullable<pdf>url='+textInput); const blob = await response.blob(); const url = window.URL.createObjectURL(New Blob([blob])); const link = document.createElement("a"c); link.href = url; link.setAttribute('download', 'awesomeIron.pdf'); document.body.appendChild(link); link.click(); link.parentNode.removeChild(link); } catch(@error) { console.@error('@Error generating PDF:', @error); } }; 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>); }
由于IronPDF仅在Node.js上运行,接下来为应用添加一个API,在Node.js上生成PDF。
在 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.error('data PDF:', 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.error('data PDF:', 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
If True Then
IronPdfGlobalConfig, PdfDocument
End If
from "@ironsoftware/ironpdf"
' Apply your IronPDF license key
IronPdfGlobalConfig.getConfig().licenseKey = "Add Your key here"
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'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.@error('data PDF:', 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();
' }
'}
注意:在上述代码中添加您自己的许可证密钥
运行您的应用:启动您的 Next.js 应用:
npm run dev
or
yarn dev
npm run dev
or
yarn dev
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'npm run dev @or yarn dev
现在输入网站 URL 以生成 PDF,然后点击生成 PDF。 将会下载名为 awesomeIron.pdf 的文件。
现在点击下拉区域并选择下载的文件。这将显示一个预览,并在底部显示名称:awesomeIron.pdf。
IronPDF page.
将许可证密钥放置在应用程序中,如下所示:
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";
IRON VB CONVERTER ERROR developers@ironsoftware.com
集成 Dropzone 与React一起使用 react-dropzone 是一个显著提升文件上传体验的简单过程。 具有拖放、文件预览和广泛定制选项等功能,react-dropzone 可以成为您的 React 项目中一个有价值的补充。 开始探索其功能,并根据您的应用需求进行定制。!
IronPDF另一方面,这是一个功能多样的 PDF 生成和操作库,使其容易集成到应用程序中。 IronPDF 提供全面的 文献资料 和 代码示例 帮助开发人员入门。
通过遵循本文中列出的步骤,您可以在您的 React 应用程序中创建一个强大的文件上传组件,并将 PDF 文件生成功能集成到现代应用程序中。