Rumah  >  Artikel  >  hujung hadapan web  >  Perkemas Muat Naik Fail dalam NestJS: Penghuraian Dalam Memori yang Cekap untuk CSV & XLSX Tanpa Storan Cakera

Perkemas Muat Naik Fail dalam NestJS: Penghuraian Dalam Memori yang Cekap untuk CSV & XLSX Tanpa Storan Cakera

DDD
DDDasal
2024-10-01 06:26:03358semak imbas

Penghuraian Fail yang Mudah dalam NestJS: Urus Muat Naik CSV dan XLSX dalam Memori untuk Kepantasan, Keselamatan dan Kebolehskalaan

pengenalan

Mengendalikan muat naik fail dalam aplikasi web adalah tugas biasa, tetapi menangani jenis fail yang berbeza dan memastikan ia diproses dengan betul boleh menjadi mencabar. Selalunya, pembangun perlu menghuraikan fail yang dimuat naik tanpa menyimpannya ke pelayan, yang amat penting untuk mengurangkan kos penyimpanan pelayan dan memastikan data sensitif tidak disimpan tanpa perlu. Dalam artikel ini, kami akan melalui proses mencipta modul NestJS tersuai untuk mengendalikan muat naik fail khusus untuk fail CSV dan XLS/XLSX, dan kami akan menghuraikan fail ini dalam ingatan menggunakan strim Node.js, jadi tiada fail statik yang dicipta pada pelayan.

Mengapa NestJS?

NestJS ialah rangka kerja Node.js progresif yang memanfaatkan TypeScript dan menyediakan seni bina aplikasi luar biasa yang membolehkan anda membina aplikasi yang boleh diuji, berskala, gandingan longgar dan mudah diselenggara. Dengan menggunakan NestJS, kami boleh memanfaatkan struktur modularnya, sistem suntikan pergantungan yang berkuasa dan ekosistem yang luas.

Langkah 1: Menyediakan Projek

Sebelum kita menyelami kod, mari sediakan projek NestJS baharu. Jika anda belum melakukannya, pasang NestJS CLI:

npm install -g @nestjs/cli

Buat projek NestJS baharu:

nest new your-super-name

Navigasi ke dalam direktori projek:

cd your-super-name

Langkah 2: Memasang Pakej yang Diperlukan

Kami perlu memasang beberapa pakej tambahan untuk mengendalikan muat naik dan penghuraian fail:

npm install @nestjs/platform-express multer exceljsfile-type
  • Multer: Perisian tengah untuk mengendalikan data berbilang bahagian/bentuk, yang digunakan terutamanya untuk memuat naik fail.
  • Exlesjs: Pustaka berkuasa untuk menghuraikan fail CSV/XLS/XLSX.
  • Jenis Fail: Pustaka untuk mengesan jenis fail strim atau penimbal.

Langkah 3: Mencipta Enjin Penyimpanan Multer Tanpa Menyimpan Fail

Untuk menyesuaikan proses muat naik fail, kami akan mencipta enjin storan Multer tersuai. Enjin ini akan memastikan bahawa hanya fail CSV dan XLS/XLSX diterima, menghuraikannya dalam memori menggunakan strim Node.js dan mengembalikan data yang dihuraikan tanpa menyimpan sebarang fail ke cakera.

Buat fail baharu untuk enjin kami:

import { PassThrough } from 'stream';
import * as fileType from 'file-type';
import { BadRequestException } from '@nestjs/common';
import { Request } from 'express';
import { Workbook } from 'exceljs';
import { createParserCsvOrXlsx } from './parser-factory.js';

const ALLOWED_MIME_TYPES = [
  'text/csv',
  'application/vnd.ms-excel',
  'text/comma-separated-values',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'application/vnd.ms-excel',
] as const;

export class CsvOrXlsxMulterEngine {
  private destKey: string;
  private maxFileSize: number;
  constructor(opts: { destKey: string; maxFileSize: number }) {
    this.destKey = opts.destKey;
    this.maxFileSize = opts.maxFileSize;
  }
  async _handleFile(req: Request, file: any, cb: any) {
    try {
      const contentLength = Number(req.headers['content-length']);
      if (
        typeof contentLength === 'number' &&
        contentLength > this.maxFileSize
      ) {
        throw new Error(`Max file size is ${this.maxFileSize} bytes.`);
      }
      const fileStream = await fileType.fileTypeStream(file.stream);
      const mime = fileStream.fileType?.mime ?? file.mimetype;
      if (!ALLOWED_MIME_TYPES.includes(mime)) {
        throw new BadRequestException('File must be *.csv or *.xlsx');
      }
      const replacementStream = new PassThrough();
      fileStream.pipe(replacementStream);
      const parser = createParserCsvOrXlsx(mime);
      const data = await parser.read(replacementStream);
      cb(null, {
        [this.destKey]:
          mime === 'text/csv' ? data : (data as Workbook).getWorksheet(),
      });
    } catch (error) {
      cb(error);
    }
  }
  _removeFile(req: Request, file: any, cb: any) {
    cb(null);
  }
}

Enjin storan tersuai ini menyemak jenis MIME fail dan memastikan ia sama ada fail CSV atau XLS/XLSX. Ia kemudian memproses fail sepenuhnya dalam ingatan menggunakan aliran Node.js, jadi tiada fail sementara dibuat pada pelayan. Pendekatan ini cekap dan selamat, terutamanya apabila berurusan dengan data sensitif.

Langkah 4: Mencipta Kilang Parser

Kilang penghurai bertanggungjawab untuk menentukan penghurai yang sesuai berdasarkan jenis fail.

Buat fail baharu untuk penghurai kami:

import excel from 'exceljs';

export function createParserCsvOrXlsx(mime: string) {
  const workbook = new excel.Workbook();
  return [
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'application/vnd.ms-excel',
  ].includes(mime)
    ? workbook.xlsx
    : workbook.csv;
}

Fungsi kilang ini menyemak jenis MIME dan mengembalikan penghurai yang sesuai (sama ada xlsx atau csv).

Langkah 5: Mengkonfigurasi Multer dalam Pengawal NestJS

Seterusnya, mari buat pengawal untuk mengendalikan muat naik fail menggunakan enjin storan tersuai kami.

Jana pengawal baharu:

nest g controller files

Dalam files.controller.ts, konfigurasikan muat naik fail menggunakan Multer dan enjin storan tersuai:

import {
  Controller,
  Post,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { Worksheet } from 'exceljs';
import { CsvOrXlsxMulterEngine } from '../../shared/multer-engines/csv-xlsx/engine.js';
import { FilesService } from './files.service.js';

const MAX_FILE_SIZE_IN_MiB = 1000000000; // Only for test

@Controller('files')
export class FilesController {
  constructor(private readonly filesService: FilesService) {}
  @UseInterceptors(
    FileInterceptor('file', {
      storage: new CsvOrXlsxMulterEngine({
        maxFileSize: MAX_FILE_SIZE_IN_MiB,
        destKey: 'worksheet',
      }),
    }),
  )
  @Post()
  create(@UploadedFile() data: { worksheet: Worksheet }) {
    return this.filesService.format(data.worksheet);
  }
}

Pengawal ini menyediakan titik akhir untuk mengendalikan muat naik fail. Fail yang dimuat naik diproses oleh CsvOrXlsxMulterEngine dan data yang dihuraikan dikembalikan dalam respons tanpa disimpan ke cakera.

Langkah 6: Menyediakan Modul

Akhir sekali, kami perlu menyediakan modul untuk memasukkan pengawal kami.

Jana modul baharu:

nest g module files

Dalam files.module.ts, import pengawal:

import { Module } from '@nestjs/common';
import { FilesController } from './files.controller.js';
import { FilesService } from './files.service.js';

@Module({
  providers: [FilesService],
  controllers: [FilesController],
})
export class FilesModule {}

Pastikan anda mengimport modul ini ke dalam AppModule anda:

Langkah 7: Menguji Muat Naik Fail dengan HTML

Untuk menguji fungsi muat naik fail, kami boleh mencipta halaman HTML ringkas yang membolehkan pengguna memuat naik fail CSV atau XLS/XLSX. Halaman ini akan menghantar fail ke titik akhir /api/files kami, di mana ia akan dihuraikan dan diproses dalam ingatan.

Berikut ialah fail HTML asas untuk menguji muat naik fail:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>File Upload</title>
</head>
<body>
    <h1>Upload a File (CSV or XLSX)</h1>
    <form action="/api/files" method="post" enctype="multipart/form-data">
        <label for="file">Choose file:</label>
        <input type="file" id="file" name="file" accept=".csv, .xlsx" required>
        <br><br>
        <button type="submit">Upload</button>
    </form>
</body>
</html>

Untuk memaparkan halaman HTML untuk muat naik fail, kami perlu memasang modul NestJS tambahan yang dipanggil @nestjs/serve-static terlebih dahulu. Anda boleh melakukan ini dengan menjalankan arahan berikut:

npm install @nestjs/serve-static

Selepas memasang, kami perlu mengkonfigurasi modul ini dalam AppModule:

import { Module } from '@nestjs/common';
import { join } from 'path';
import { ServeStaticModule } from '@nestjs/serve-static';
import { FilesModule } from './modules/files/files.module.js';

@Module({
  imports: [
    FilesModule,
    ServeStaticModule.forRoot({
      rootPath: join(new URL('..', import.meta.url).pathname, 'public'),
      serveRoot: '/',
    }),
  ],
})
export class AppModule {}

Persediaan ini akan membolehkan kami menyampaikan fail statik daripada direktori awam. Kini, kami boleh membuka halaman muat naik fail dengan menavigasi ke http://localhost:3000 dalam penyemak imbas anda.

Streamline File Uploads in NestJS: Efficient In-Memory Parsing for CSV & XLSX Without Disk Storage

Muat Naik Fail Anda

Untuk memuat naik fail, ikut langkah berikut:

  1. Pilih fail dengan mengklik butang ‘Pilih fail’.
  2. Klik pada butang ‘Muat Naik’ untuk memulakan proses muat naik.

Setelah fail berjaya dimuat naik, anda akan melihat pengesahan bahawa fail telah dimuat naik dan diformatkan.

Streamline File Uploads in NestJS: Efficient In-Memory Parsing for CSV & XLSX Without Disk Storage

Nota: Saya tidak memasukkan kod untuk memformat fail yang dimuat naik, kerana ini bergantung pada pustaka yang anda pilih untuk memproses fail CSV atau XLS/XLSX. Anda boleh melihat pelaksanaan lengkap pada GitHub.
Membandingkan Kebaikan dan Keburukan Pemprosesan Fail Dalam Memori
Apabila memutuskan sama ada untuk menggunakan pemprosesan fail dalam memori atau menyimpan fail ke cakera, adalah penting untuk memahami pertukaran.

Kebaikan Pemprosesan Dalam Memori:

Tiada Fail Sementara pada Cakera:

  • Keselamatan: Data sensitif tidak ditinggalkan pada cakera pelayan, mengurangkan risiko kebocoran data.
  • Kecekapan Sumber: Pelayan tidak perlu memperuntukkan ruang cakera untuk fail sementara, yang boleh berguna terutamanya dalam persekitaran dengan storan terhad.

Pemprosesan Lebih Cepat:

  • Prestasi: Menghuraikan fail dalam memori boleh menjadi lebih pantas kerana ia menghilangkan overhed menulis dan membaca fail daripada cakera.
  • Operasi I/O yang dikurangkan: Operasi I/O cakera yang lebih sedikit bermakna kependaman yang lebih rendah dan kuat daya pemprosesan yang lebih tinggi untuk pemprosesan fail.

Pembersihan Ringkas:

  • Tiada Pembersihan Diperlukan: Memandangkan fail tidak disimpan ke cakera, tidak perlu mengurus atau membersihkan fail sementara, memudahkan pangkalan kod.

Keburukan Pemprosesan Dalam Memori:

Penggunaan Memori:

  • Penggunaan Memori Tinggi: Fail yang besar boleh menggunakan sejumlah besar memori, yang mungkin membawa kepada ralat kehabisan ingatan jika pelayan tidak mempunyai sumber yang mencukupi.
  • Skalabiliti: Mengendalikan fail besar atau berbilang muat naik fail secara serentak mungkin memerlukan pengurusan memori yang teliti dan strategi penskalaan.

Had Saiz Fail:

  • Terhad oleh Memori: Saiz fail maksimum yang boleh diproses dihadkan oleh memori yang tersedia pada pelayan. Ini boleh menjadi signifikan kelemahan semut untuk aplikasi yang berurusan dengan fail yang sangat besar.

Kerumitan dalam Pengendalian Ralat:

  • Pengurusan Ralat: Mengurus ralat dalam penstriman data boleh menjadi lebih kompleks daripada mengendalikan fail pada cakera, terutamanya dalam kes di mana data separa mungkin perlu dipulihkan atau dianalisis.

Bila hendak menggunakan Pemprosesan Dalam Memori:

Fail Kecil hingga Sederhana: Jika aplikasi anda berurusan dengan fail yang agak kecil, pemprosesan dalam memori boleh menawarkan kelajuan dan kesederhanaan.

Aplikasi Sensitif Keselamatan: Apabila mengendalikan data sensitif yang tidak sepatutnya disimpan pada cakera, pemprosesan dalam memori boleh mengurangkan risiko pelanggaran data.

Senario Berprestasi Tinggi: Aplikasi yang memerlukan daya pemprosesan tinggi dan kependaman minimum mungkin mendapat manfaat daripada pengurangan overhed pemprosesan dalam memori.

Bila Perlu Pertimbangkan Pemprosesan Berasaskan Cakera:

Fail Besar: Jika aplikasi anda perlu memproses fail yang sangat besar, pemprosesan berasaskan cakera mungkin diperlukan untuk mengelakkan kehabisan memori.

Persekitaran Terkandas Sumber: Dalam kes di mana memori pelayan terhad, pemprosesan fail pada cakera boleh menghalang keletihan memori dan membolehkan pengurusan sumber yang lebih baik.

Keperluan Storan Berterusan: Jika anda perlu menyimpan salinan fail yang dimuat naik untuk pengauditan, sandaran atau pengambilan kemudian, menyimpan fail ke cakera adalah perlu.

Integrasi dengan Perkhidmatan Storan Luaran: Untuk fail besar, pertimbangkan untuk memuat naiknya ke perkhidmatan storan luaran seperti AWS S3, Google Cloud

  • Storan atau Storan Blob Azure. Perkhidmatan ini membolehkan anda memunggah storan daripada pelayan anda dan anda boleh memproses fail dalam awan atau mendapatkannya semula untuk pemprosesan dalam memori mengikut keperluan.

Skalabiliti: Penyelesaian storan awan boleh mengendalikan fail besar-besaran dan memberikan lebihan, memastikan data anda selamat dan mudah diakses dari berbilang lokasi geografi.

Kecekapan Kos: Menggunakan storan awan boleh menjadi lebih kos efektif untuk mengendalikan fail besar, kerana ia mengurangkan keperluan untuk sumber pelayan tempatan dan menyediakan harga bayar semasa anda pergi.

Kesimpulan

Dalam artikel ini, kami telah mencipta modul muat naik fail tersuai dalam NestJS yang mengendalikan fail CSV dan XLS/XLSX, menghuraikannya dalam memori dan mengembalikan data yang dihuraikan tanpa menyimpan sebarang fail ke cakera. Pendekatan ini memanfaatkan kuasa strim Node.js, menjadikannya cekap dan selamat, kerana tiada fail sementara ditinggalkan pada pelayan.

Kami juga telah meneroka kebaikan dan keburukan pemprosesan fail dalam memori berbanding menyimpan fail ke cakera. Walaupun pemprosesan dalam memori menawarkan kelajuan, keselamatan dan kesederhanaan, adalah penting untuk mempertimbangkan penggunaan memori dan potensi had saiz fail sebelum menggunakan pendekatan ini.

Sama ada anda sedang membina aplikasi perusahaan atau projek kecil, pengendalian muat naik dan penghuraian fail dengan betul adalah penting. Dengan persediaan ini, anda sedang dalam perjalanan untuk menguasai muat naik fail dalam NestJS tanpa perlu risau tentang storan pelayan atau isu keselamatan data yang tidak perlu.

Jangan ragu untuk berkongsi pendapat dan penambahbaikan anda di bahagian komen di bawah!

Jika anda menyukai artikel ini atau mendapati alatan ini berguna, pastikan anda mengikuti saya di Dev.to untuk mendapatkan lebih banyak cerapan dan petua tentang pengekodan dan pembangunan. Saya kerap berkongsi kandungan yang berguna untuk menjadikan perjalanan pengekodan anda lebih lancar.

Ikuti saya di X (Twitter), tempat saya berkongsi lebih banyak pemikiran, kemas kini dan perbincangan yang menarik tentang pengaturcaraan dan teknologi! Jangan ketinggalan - klik butang ikuti itu.

Anda juga boleh mengikuti saya di LinkedIn untuk mendapatkan pandangan profesional, kemas kini tentang projek terbaharu saya dan perbincangan tentang pengekodan, aliran teknologi dan banyak lagi. Jangan ketinggalan kandungan berharga yang boleh membantu anda meningkatkan kemahiran pembangunan anda - jom berhubung!

Atas ialah kandungan terperinci Perkemas Muat Naik Fail dalam NestJS: Penghuraian Dalam Memori yang Cekap untuk CSV & XLSX Tanpa Storan Cakera. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn