Penghuraian Fail yang Mudah dalam NestJS: Urus Muat Naik CSV dan XLSX dalam Memori untuk Kepantasan, Keselamatan dan Kebolehskalaan
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.
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.
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
Kami perlu memasang beberapa pakej tambahan untuk mengendalikan muat naik dan penghuraian fail:
npm install @nestjs/platform-express multer exceljsfile-type
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.
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).
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.
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:
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.
Muat Naik Fail Anda
Untuk memuat naik fail, ikut langkah berikut:
Setelah fail berjaya dimuat naik, anda akan melihat pengesahan bahawa fail telah dimuat naik dan diformatkan.
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.
Tiada Fail Sementara pada Cakera:
Pemprosesan Lebih Cepat:
Pembersihan Ringkas:
Penggunaan Memori:
Had Saiz Fail:
Kerumitan dalam Pengendalian Ralat:
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.
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
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.
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!