将 Excel 转换为 JSON - 使用 React-Dropzone(可能是客户端)
Convert Excel to JSON - using React-Dropzone (client side probably)
这类似于问题:,但使用了 React 和 Dropzone。
我需要将 Excel 文件上传到服务器并在那里解析,或者在浏览器中将其解析到 JSON,然后上传 JSON.
我已经编写了 React(前端)和服务器端(后端)来处理 CSV 文件并存储到 MongoDB。下面是 React 端。
我的两个问题是:
如果我在客户端执行,如何使用 XSLX 或 sheetjs 读取和处理使用 DropZone 删除的文件
如果我在服务器上执行此操作,如何正确上传 Excel 文件(我已阅读有关为 Office/Excel 设置 Mime-Extension 的帖子)。我已经能够上传文件,但上传后我无法在 Excel 中打开它。它通常是两倍大小,可能是 UTF-8 到 UTF-16 的转换。
import React, {useCallback, useState} from 'react';
import {useDropzone} from 'react-dropzone' // use hooks
import Dropzone from 'react-dropzone'
import XLSX from 'xlsx'
//import logo1 from './logo.svg'; // original
import logo2 from './images/ShedMadeOfWood_small.jpg'; // demo logo
import './App.css';
function App() {
// Edit <code>src/App.js</code> and save to reload.
// const [files, setFiles] = useState([])
const currDateTime1 = new Date().toISOString()
console.warn(currDateTime1 + " Starting React/App: function App()")
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
const currDateTime2 = new Date().toISOString()
console.log(currDateTime2 + " trying to read file")
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = (data) => {
// Do what you want with the file contents
//console.log("file size:", data.length);
//const binaryStr = reader.result
//const fileContents = reader.readAsText
const fileContents = data.target.result
const currDateTime3 = new Date().toISOString()
console.log(currDateTime3 + " Text print of file contents:")
// console.log(fileContents)
// This fetch worked for CSV file
fetch('http://localhost:3001/api/filedata', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
// TODO - could add userid, datetime here, filename, etc...
body: JSON.stringify({
"fileContents": fileContents
//, secondParam: 'yourOtherValue',
})
})
// another example passed formData to the body:
/*
fetch('http://localhost:3001/api/filedatabinary', {
method: 'POST',
body: fileContents
})
*/
}
reader.readAsText(file)
//reader.readAsBinaryString(file)
})
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone ({onDrop})
const [fileNames, setFileNames] = useState([]);
const handleDrop = acceptedFiles =>
setFileNames(acceptedFiles.map(file => file.name));
return (
<div align="center">
<div className="App" {...getRootProps()}>
<header className="App-header">
<img src={logo2} className="App-logo" alt="logo" />
</header>
<h4>CSV Files here</h4>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<div>
<p>Drag and Drop a csv file here,<br />
or click to select files.</p>
</div>
}
</div>
<h4>Drop Excel Files Here</h4>
<Dropzone onDrop={handleDrop}>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag and drop Excel files, or click to select files</p>
</div>
)}
</Dropzone>
<div>
<strong>Excel File(s):</strong>
<ul>
{fileNames.map(fileName => (
<li key={fileName}>{fileName}</li>
))}
</ul>
</div>
<hr />
<br /><br />
Thanks for using our company!
</div>
);
}
export default App;
我的服务器端代码拆分并循环遍历 CSV 的行,并将它们保存到 MongoDB 作为 JSON。我将 CSV 文件的内容作为 JSON 变量的单个值上传,然后在服务器上对其进行解析。我最近的更改是使用两种不同的技术添加两个拖放区,一个用于 CSV,一个用于 Excel。如果需要,我可以在服务器上使用两种不同的 REST 方法,一种用于 CSV,另一种用于二进制。或者我可以在客户端转换为 JSON,而在服务器上只有一个 REST 方法。
基于此 post 在客户端上运行 XLSX:。
也就是说,浏览器端将Excel转换为JSON,而post将JSOn转换为服务器端。我假设只有一个工作表,只有在有多个工作表时才转换第一个。
我不完全确定为什么他需要两种类型的 readAsBinaryString 和 readAsArrayBuffer,但它工作正常。
const handleExcelDrop = (acceptedFiles) => {
console.log("handleExcelDrop")
setFileNames(acceptedFiles.map(file => file.name));
acceptedFiles.forEach((file) => {
console.log("handleExcelDrop:forEach(file)")
// See
const reader = new FileReader()
const rABS = !!reader.readAsBinaryString; // !! converts object to boolean
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = (e) => {
// Do what you want with the file contents
var bstr = e.target.result;
var workbook = XLSX.read(bstr, { type: rABS ? "binary" : "array" })
var sheet_name_list = workbook.SheetNames[0];
var jsonFromExcel = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list], {
raw: false,
dateNF: "MM-DD-YYYY",
header:1,
defval: ""
})
console.log("jsonFromExcel object=")
console.log(jsonFromExcel)
console.log("jsonFromExcel string=")
console.log(JSON.stringify(jsonFromExcel))
fetch('http://localhost:3001/api/filedataExcel', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
// TODO - could add userid, datetime here, filename, etc...
jsonFromExcel
})
}
if (rABS) reader.readAsBinaryString(file);
else reader.readAsArrayBuffer(file);
})
}
当然还有顶部的导入:
import XLSX from 'xlsx'
稍后我将不得不添加逻辑以查看如果他们丢弃 Excel 文件以外的其他内容会发生什么。
这类似于问题:
我需要将 Excel 文件上传到服务器并在那里解析,或者在浏览器中将其解析到 JSON,然后上传 JSON.
我已经编写了 React(前端)和服务器端(后端)来处理 CSV 文件并存储到 MongoDB。下面是 React 端。
我的两个问题是:
如果我在客户端执行,如何使用 XSLX 或 sheetjs 读取和处理使用 DropZone 删除的文件
如果我在服务器上执行此操作,如何正确上传 Excel 文件(我已阅读有关为 Office/Excel 设置 Mime-Extension 的帖子)。我已经能够上传文件,但上传后我无法在 Excel 中打开它。它通常是两倍大小,可能是 UTF-8 到 UTF-16 的转换。
import React, {useCallback, useState} from 'react';
import {useDropzone} from 'react-dropzone' // use hooks
import Dropzone from 'react-dropzone'
import XLSX from 'xlsx'
//import logo1 from './logo.svg'; // original
import logo2 from './images/ShedMadeOfWood_small.jpg'; // demo logo
import './App.css';
function App() {
// Edit <code>src/App.js</code> and save to reload.
// const [files, setFiles] = useState([])
const currDateTime1 = new Date().toISOString()
console.warn(currDateTime1 + " Starting React/App: function App()")
const onDrop = useCallback(acceptedFiles => {
// Do something with the files
const currDateTime2 = new Date().toISOString()
console.log(currDateTime2 + " trying to read file")
acceptedFiles.forEach((file) => {
const reader = new FileReader()
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = (data) => {
// Do what you want with the file contents
//console.log("file size:", data.length);
//const binaryStr = reader.result
//const fileContents = reader.readAsText
const fileContents = data.target.result
const currDateTime3 = new Date().toISOString()
console.log(currDateTime3 + " Text print of file contents:")
// console.log(fileContents)
// This fetch worked for CSV file
fetch('http://localhost:3001/api/filedata', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
// TODO - could add userid, datetime here, filename, etc...
body: JSON.stringify({
"fileContents": fileContents
//, secondParam: 'yourOtherValue',
})
})
// another example passed formData to the body:
/*
fetch('http://localhost:3001/api/filedatabinary', {
method: 'POST',
body: fileContents
})
*/
}
reader.readAsText(file)
//reader.readAsBinaryString(file)
})
}, [])
const {getRootProps, getInputProps, isDragActive} = useDropzone ({onDrop})
const [fileNames, setFileNames] = useState([]);
const handleDrop = acceptedFiles =>
setFileNames(acceptedFiles.map(file => file.name));
return (
<div align="center">
<div className="App" {...getRootProps()}>
<header className="App-header">
<img src={logo2} className="App-logo" alt="logo" />
</header>
<h4>CSV Files here</h4>
<input {...getInputProps()} />
{
isDragActive ?
<p>Drop the files here ...</p> :
<div>
<p>Drag and Drop a csv file here,<br />
or click to select files.</p>
</div>
}
</div>
<h4>Drop Excel Files Here</h4>
<Dropzone onDrop={handleDrop}>
{({ getRootProps, getInputProps }) => (
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<p>Drag and drop Excel files, or click to select files</p>
</div>
)}
</Dropzone>
<div>
<strong>Excel File(s):</strong>
<ul>
{fileNames.map(fileName => (
<li key={fileName}>{fileName}</li>
))}
</ul>
</div>
<hr />
<br /><br />
Thanks for using our company!
</div>
);
}
export default App;
我的服务器端代码拆分并循环遍历 CSV 的行,并将它们保存到 MongoDB 作为 JSON。我将 CSV 文件的内容作为 JSON 变量的单个值上传,然后在服务器上对其进行解析。我最近的更改是使用两种不同的技术添加两个拖放区,一个用于 CSV,一个用于 Excel。如果需要,我可以在服务器上使用两种不同的 REST 方法,一种用于 CSV,另一种用于二进制。或者我可以在客户端转换为 JSON,而在服务器上只有一个 REST 方法。
基于此 post 在客户端上运行 XLSX:
也就是说,浏览器端将Excel转换为JSON,而post将JSOn转换为服务器端。我假设只有一个工作表,只有在有多个工作表时才转换第一个。
我不完全确定为什么他需要两种类型的 readAsBinaryString 和 readAsArrayBuffer,但它工作正常。
const handleExcelDrop = (acceptedFiles) => {
console.log("handleExcelDrop")
setFileNames(acceptedFiles.map(file => file.name));
acceptedFiles.forEach((file) => {
console.log("handleExcelDrop:forEach(file)")
// See
const reader = new FileReader()
const rABS = !!reader.readAsBinaryString; // !! converts object to boolean
reader.onabort = () => console.log('file reading was aborted')
reader.onerror = () => console.log('file reading has failed')
reader.onload = (e) => {
// Do what you want with the file contents
var bstr = e.target.result;
var workbook = XLSX.read(bstr, { type: rABS ? "binary" : "array" })
var sheet_name_list = workbook.SheetNames[0];
var jsonFromExcel = XLSX.utils.sheet_to_json(workbook.Sheets[sheet_name_list], {
raw: false,
dateNF: "MM-DD-YYYY",
header:1,
defval: ""
})
console.log("jsonFromExcel object=")
console.log(jsonFromExcel)
console.log("jsonFromExcel string=")
console.log(JSON.stringify(jsonFromExcel))
fetch('http://localhost:3001/api/filedataExcel', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
// TODO - could add userid, datetime here, filename, etc...
jsonFromExcel
})
}
if (rABS) reader.readAsBinaryString(file);
else reader.readAsArrayBuffer(file);
})
}
当然还有顶部的导入:
import XLSX from 'xlsx'
稍后我将不得不添加逻辑以查看如果他们丢弃 Excel 文件以外的其他内容会发生什么。