以下是我编写 HTML/Javascript/PyScript 代码的失败尝试,该代码允许用户上传 csv(或 excel)文件,然后该文件可在 PyScript(例如 Pandas)中使用。正如您可能注意到的,我对 Javascript 不太有经验。
<html>
<head>
<link rel="stylesheet" href="https://pyscript.net/latest/pyscript.css" />
<script defer src="https://pyscript.net/latest/pyscript.js"></script>
<py-config>
packages = ["pandas"]
</py-config>
</head>
<body>
<input type="file" id="fileinput" accept=".csv, .xlsx"/>
<script>
var test = "test";
function assignFile(e) {
// Assign file to js variable
window.file = e.target.files[0];
console.log("File assigned")
}
</script>
<py-script>
import pandas as pd
import js
import pyodide
from js import test
js.console.log(test)
def get_file(e):
js.console.log("Attempting file upload: " + e.target.value)
# Assign file to a js variable
js.assignFile(e)
# Import variable to python
from js import file
display(pd.read_csv(file))
get_file_proxy = pyodide.ffi.create_proxy(get_file)
js.document.getElementById("fileinput").addEventListener("change", get_file_proxy)
</py-script>
</body>
</html>
此代码的一些注释:我知道 script
中编写的部分元素也可以写在 py-script
中元素,但决定不这样做。此外,行 from js import file
imports the variable created in Javascript ,但是当我尝试在 Pandas 中使用此变量时,它在控制台中给出错误 Invalid file path or buffer object type: <class 'pyodide.JsProxy'>
。这与正常运行的行 from js import test
相反。 。但是,具体错误对我的问题并不重要,即:
允许用户上传 csv(或 xlsx)文件以在 PyScript 中使用的简单方法是什么?
最佳答案
首先,您需要使用 FileEvent
的 event.target.files
属性。可以使用常见的异步 JavaScript 方法来读取它,例如 .text()
或 .arrayBuffer()
。使用 pandas 从文本中读取 CSV 文件 you need to use an in-memory stream ,如 io.StringIO 或 io.BytesIO 。
我调整了你的 PyScript 代码,如下所示:
import pandas as pd
import pyodide
import io
import js
async def get_file(e):
files = e.target.files.to_py()
for file in files:
file_content = await file.text()
df = pd.read_csv(io.StringIO(file_content))
js.console.log(df)
get_file_proxy = pyodide.ffi.create_proxy(get_file)
js.document.getElementById("fileinput").addEventListener("change", get_file_proxy)
请记住,使用缓冲区可能会更好地读取大文件,但我并不完全了解 PyScript 中的最佳实践。
关于javascript - 上传 csv 以在 PyScript 中处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75231502/