如何将所有格式的excel文件上传/下载到azure blob存储Nodejs服务器端

Posted

技术标签:

【中文标题】如何将所有格式的excel文件上传/下载到azure blob存储Nodejs服务器端【英文标题】:How to upload / download all format excel file to azure blob storage Nodejs server side 【发布时间】:2021-04-15 14:45:57 【问题描述】:

我正在尝试将 excel 文件上传到 azure blob 存储

import  DefaultAzureCredential  from '@azure/identity';
import  BlobServiceClient  from '@azure/storage-blob';

// Enter your storage account name
const account = process.env.ACCOUNT_NAME;

// Unique name for the container
const containerName = process.env.CONTAINER_NAME;

// Azure AD Credential information is required to run this sample:
if (
  !process.env.AZURE_TENANT_ID ||
  !process.env.AZURE_CLIENT_ID ||
  !process.env.AZURE_CLIENT_SECRET || !account || !containerName
) 
  return next(SystemResponse.badRequestError('Azure AD authentication information not provided, but it is required to run this sample. Exiting.'));


const defaultAzureCredential = new DefaultAzureCredential();
const blobServiceClient = new BlobServiceClient(
  `https://$account.blob.core.windows.net`,
  defaultAzureCredential,
);



// Get a reference to a container
const containerClient = blobServiceClient.getContainerClient(containerName);

// Upload data to the blob
const blobName = `$req.files.file.name.split('.')[0]+$new Date().getTime().$req.files.file.name.split('.')[1]`;

// create blobClient for container
const blockBlobClient = containerClient.getBlockBlobClient(blobName);

// upload file
const uploadBlobResponse = await blockBlobClient.upload(`$containerName$req.files.file.path`, req.files.file.size);

我正在使用邮递员上传excel文件,但是,只有文件路径存储在excel文件中,实际上是内容,我该如何解决这个问题请帮忙? && on download file name 即将响应

【问题讨论】:

【参考方案1】:

我创建了一个azure function,也许您可​​以使用parse-multipart 来接收您的文件:

安装:

npm install parse-multipart

代码:

import  AzureFunction, Context, HttpRequest  from "@azure/functions"
import  DefaultAzureCredential  from '@azure/identity';
import  BlobServiceClient  from '@azure/storage-blob';

const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> 
    var multipart = require('parse-multipart');
    var bodyBuffer = Buffer.from(req.body);
    var boundary = multipart.getBoundary(req.headers['content-type']);
    var parts = multipart.Parse(bodyBuffer, boundary);

    // Enter your storage account name
    const account = process.env.ACCOUNT_NAME;

    // Unique name for the container
    const containerName = process.env.CONTAINER_NAME;

    // Azure AD Credential information is required to run this sample:
    if (
      !process.env.AZURE_TENANT_ID ||
      !process.env.AZURE_CLIENT_ID ||
      !process.env.AZURE_CLIENT_SECRET || !account || !containerName
    ) 
      return next(SystemResponse.badRequestError('Azure AD authentication information not provided, but it is required to run this sample. Exiting.'));
    

    const defaultAzureCredential = new DefaultAzureCredential();
    const blobServiceClient = new BlobServiceClient(
      `https://$account.blob.core.windows.net`,
      defaultAzureCredential,
    );



    // Get a reference to a container
    const containerClient = blobServiceClient.getContainerClient(containerName);

    // Upload data to the blob
    const blobName = `$parts[0].filename.split('.')[0]+$new Date().getTime().$parts[0].filename.split('.')[1]`;

    // create blobClient for container
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);

    // upload file
    const uploadBlobResponse = await blockBlobClient.upload(parts[0].data , parts[0].data.length);
;

原因:

function upload(body: HttpRequestBody, contentLength: number, options?: BlockBlobUploadOptions)

HttpRequestBody 的值应该是Blob, string, ArrayBuffer, ArrayBufferView or a function which returns a new Readable stream whose offset is from data source beginning,所以你不应该使用路径。

================更新========================

根据讨论,文件要根据相对路径读取,文件的二进制数据要转换成base64字符串。

var fs = require('fs');
var path = require('path'); 
//set relative path to file 
let relativePath = path.relative(process.cwd(),$req.files.file.path); 
//reading binary data of file 
let binaryData=fs.readFileSync(relativePath); 
//converting binary data to base64 string 
let base64String=Buffer.from(binaryData).toString("base64")
await blockBlobClient.upload(base64String, req.files.file.size);

================update2====================

    const containerClient = blobServiceClient.getContainerClient(containerName);

    // Upload data to the blob
    const blobName = `xxx.xlsx`;

    // create blobClient for container
    const blockBlobClient = containerClient.getBlockBlobClient(blobName);

    const downloadBlockBlobResponse = blockBlobClient.downloadToFile("D:\\xxx\\xxx.xlsx");

【讨论】:

感谢您的回复,但是,我正在尝试上传 excel 文件,请求中:- req.files.file 将提供要上传的文件,我正在使用邮递员选择 excel 文件,请确认,是否:- var bodyBuffer = Buffer.from(req.files.file);将在这里工作或我通过什么,以便文件以正确的格式上传到 azure 并按原样下载? var bodyBuffer = Buffer.from(req.body);中的参数是你的邮递员发送的请求体,在这个format中。可以的话,直接放请求体,按照我的代码应该是没有问题的。 如果您不想使用我的代码,请告诉我您的请求类型是什么?我使用HttpRequest 就我而言,我使用的是 const multipart = require("connect-multiparty"); const multipartMiddleware = multipart();当我在邮递员中选择文件时,此代码给出:- req.files:- 它给出了所有文件详细信息:- file: fieldName: 'file', originalFilename: 'Productivity Manager - Task Tracking .xlsx', path: '/tmp/hFX6uhx6j50ubboYhmCHDxeS.xlsx', headers: 'content-disposition': '表格数据;名称=“文件”; filename="Productivity Manager - Task Tracking .xlsx"', 'content-type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' , size: 17619, name: 'Productivity Manager - Task Tracking .xlsx',类型:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'

以上是关于如何将所有格式的excel文件上传/下载到azure blob存储Nodejs服务器端的主要内容,如果未能解决你的问题,请参考以下文章

如何从 azure 函数应用程序将文件发送到 azure 存储

如何在 Azure Pipeline 上使用 Terraform 将文件上传到 Azure 存储?

如何在 Python 中将 Azure Blob 文件 CSV 转换为 Excel

论文指导如何上传多个文件?

如何上传Excel直接读取里面的数据,不用鎒xcel文件后再读取

查看本地SPT上传到Microsoft Azure临时存储区是否成功的方法