ایجاد اسناد ورد با Node.js – از صفر تا صد
نرمافزار مایکروسافت ورد یک واژهپرداز قدرتمند است. این نرمافزار، فرمت رایجی برای ساخت و مبادله اسناد به صورت doc یا docx ارائه کرده است. یکی از قابلیتهای بسیاری از اپلیکیشنهای مرتبط با تولید و پردازش اسناد، امکان ایجاد اسناد ورد از انواع مختلف اسناد است. ایجاد اسناد ورد با Node.js با بهرهگیری از کتابخانههای شخص ثالث کار آسانی است.
در این مقاله اپلیکیشنی طراحی میکنیم که به کاربران امکان میدهد اسناد خود را در یک ویرایشگر متنی وارد کرده و از روی آن اسناد ورد بسازند. بکاند این اپلیکیشن با Express و فرانتاند آن با React طراحی میشود.
بخش بکاند
کار خود را از بکاند آغاز میکنیم.
برای شروع یک پوشه پروژه میسازیم که پوشه backend درون آن قرار دارد. سپس در پوشه backend دستور زیر را اجرا میکنیم تا یک اپلیکیشن اکسپرس ایجاد شود:
npx express-generator
سپس دستور npm i را اجرا میکنیم تا پکیجها نصب شوند و بعد پکیجهای خود را نصب میکنیم. ما به Babel برای اجرای اپلیکیشن با جدیدترین نسخه جاوا اسکریپت نیاز داریم، CORS برای درخواستهای بین دامنهای در فرانتاند، HTML-DOCX-JS برای تبدیل رشتههای HTML به اسناد ورد، Multer برای آپلود فایل، Sequelize برای ORM و در نهایت SQLite3 برای پایگاه داده مورد استفاده قرار خواهند گرفت.
همه این موارد را با اجرای دستور زیر نصب میکنیم:
npm i @babel/cli @babel/core @babel/node @babel/preset-env cors html-docx-js sequelize sqlite3 multer
پس از آن، بخش scripts فایل package.json را به صورت زیر تغییر میدهیم:
"start": "nodemon --exec npm run babel-node --./bin/www", "babel-node": "babel-node"
بدین ترتیب اپلیکیشن خود را به جای محیط اجرای معمول Node با استفاده از Babel اجرا میکنیم. سپس یک فایل .babelrc در پوشه backend ساخته و کد زیر را به آن اضافه میکنیم:
{ "presets": [ "@babel/preset-env" ] }
بدین ترتیب اپلیکیشنمان میتواند با آخرین نسخه از جاوا اسکریپت اجرا شود. سپس کد پایگاه داده خود را اضافه میکنیم. به این منظور دستور زیر را در پوشه backend اجرا کنید تا کد Sequelize ایجاد شود:
npx sequelize-cli init
اینک باید فایل config.js را در ساختار پروژه خود داشته باشیم. کد زیر را به این فایل اضافه میکنیم:
{ "development": { "dialect": "sqlite", "storage": "development.db" }, "test": { "dialect": "sqlite", "storage": "test.db" }, "production": { "dialect": "sqlite", "storage": "production.db" } }
کد فوق تعیین میکند که از SQLite به عنوان پایگاه داده استفاده خواهیم کرد. سپس مدل و migration را با اجرای دستور زیر ایجاد میکنیم. این دستور برای ایجاد یک مدل Document و جدول Documents استفاده میشود.
npx sequelize-cli model:create --name Document --attributes name:string,document:text,documentPath:string
برای ایجاد پایگاه داده دستور زیر را اجرا کنید:
npx sequelize-cli db:migrate
سپس مسیرها (routes) را ایجاد میکنیم. به این منظور یک فایل به نام document.js در پوشه routes ساخته و کد زیر را به آن اضافه کنید:
در 4 مسیر نخست، عملیات استاندارد CRUD را روی جدول Documents اجرا میکنیم. برای دریافت همه Document-ها عملیات GET را داریم. عملیات POST برای ایجاد یک Document از پارامترها استفاده میشود. عملیات PUT برای بهروزرسانی Document بر اساس ID مورد استفاده قرار میگیرد و عملیات DELETE برای حذف کردن یک Document بر اساس ID آن استفاده میشود. کد HTML را در فیلد document برای تولید سند ورد در ادامه خواهیم داشت.
مسیر generate برای تولید سند ورد استفاده میشود. بدین ترتیب ID از URL به دست میآید و سپس از پکیج HTML-DOCX-JS برای تولید سند ورد استفاده میشود. اسناد ورد با تبدیل سند HTML به یک شیء استریم فایل با پکیج HTML-DOCX-JS و سپس نوشتن استریم در یک فایل و ذخیره مسیر فایل در مدخل Document به همراه ID در پارامتر URL تولید میشوند.
همچنین یک مسیر uploadImage داریم که به کاربر امکان میدهد تا تصاویر را با افزونه CKEditor و CKFinder آپلود کند. این افزونه در پاسخ منتظر uploaded و url است و لذا این موارد را بازگشت میدهیم.
سپس باید یک پوشه به نام files به پوشه backend اضافه کنیم. در ادامه در فایل app.js کد موجود را با کد زیر عوض میکنیم:
پوشه فایل را با دستور زیر عرضه میکنیم:
و مسیر document را نیز با دستور زیر عرضه میکنیم:
بخش فرانتاند
اکنون کار ساخت بکاند پایان یافته است و میتوانیم به فرانتاند اپلیکیشن خود بپردازیم.
یک اپلیکیشن ریاکت با اجرای اسکریپت Create React App بسازید. دستور زیر را در پوشه root پروژه اجرا کنید:
npx create-react-app frontend
سپس پکیجها را نصب میکنیم. از CKEditor برای ویرایشگر متنی خود استفاده میکنیم. از Axios برای ایجاد درخواستهای HTTP، از Bootstrap برای استایلبندی، از MobX برای مدیریت ساده حالت، از React Router برای مسیریابی URL-ها به کامپوننتها و از Formik و Yup به ترتیب برای مدیریت مقادیر فرم و اعتبارسنجی فرم استفاده میکنیم.
پکیجهای فوق را میتوانید با دستور زیر نصب کنید:
npm i @ckeditor/ckeditor5-build-classic @ckeditor/ckeditor5-react axios bootstrap formik mobx mobx-react react-bootstrap react-router-dom yup
زمانی که پکیجها نصب شدند، میتوانیم کار ساخت فرانتاند خود را آغاز کنیم. در فایل App.js کد موجود را با کد زیر عوض میکنیم:
کد فوق نوار فوقانی و صفحه اصلی اپلیکیشن را ایجاد میکند. در فایل App.css کد موجود را با کد زیر عوض میکنیم:
بدین ترتیب مقداری padding به صفحه اضافه میشود و پیام اعتبارسنجی برای ویرایشگر متنی استایلبندی میشود. همچنین رنگ navbar تغییر مییابد. در ادامه یک فرم ایجاد میکنیم تا بتوانیم سندها را اضافه کرده و ویرایش کنیم. یک فایل به نام DocumentForm.js در پوشه src ایجاد کرده و کد زیر را به آن اضافه کنید:
ما Form بوتاسترپ خود را درون یک کامپوننت Formik قرار میدهیم تا کارکرد مدیریت فرم را از طریق Formik به دست آوریم که مستقیماً در فیلدهای فرم بوتاسترپ ریاکت استفاده میکنیم. این کار را در مورد افزونه CKEditor نمیتوانیم انجام دهیم، از این رو «دستگیرههای فرم» (Form Handlers) خاص خود را برای ویرایشگر متنی مینویسیم. مقدار prop به نام data را برابر با مقدار ورودی از ویرایشگر متنی قرار میدهیم. تابع onInit زمانی استفاده میشود که کاربران تلاش میکنند، سند موجود را ویرایش کنند. از آنجا باید prop به نام data را با ویرایشگر تعیین کنیم، آن را با اجرای دستور زیر مقداردهی میکنیم:
prop به نام onChange یک تابع handler برای تعیین content در زمانهای بهروزرسانی شدن است. از این رو prop به نام data آخرین مقدار را خواهد داشت که وقتی کاربر روی Save کلیک میکند تحویل میشود. از افزونه CKFinder برای آپلود تصاویر استفاده میکنیم. برای عملیاتی ساختن آن باید URL تصویر آپلود شونده را به URL مسیر آپلود در بکاند تنظیم کنیم. اسکیمای اعتبارسنجی فرم از سوی شیء schema در Yup عرضه میشود که در ابتدای کد ایجاد شده است. بررسی میکنیم که آیا فیلد name پر شده است یا نه.
تابع handleSubmit فرایند تحویل دادهها به بکاند را مدیریت میکند. هر دو شیء content و evt را بررسی میکنیم تا در مورد هر دو فیلد مطمئن شویم، زیرا نمیتوانیم از Formik مربوط به دستگیرههای فرم مستقیماً درون کامپوننت CKEditor استفاده کنیم. اگر همه چیز معتبر باشد، در این صورت میتوانیم به یک سند جدید اشاره کنیم و آن را بسته به این که prop به نام edit مقدار true یا false دارد، بهروزرسانی کنیم. سپس هنگامی که ذخیره سند موفق باشد، getAllDocuments را فراخوانی میکنیم تا جدیدترین سندها در استور MobX با دستور زیر پر شوند:
سپس با ایجاد فایل HomePage.js در پوشه src صفحه اصلی اپلیکیشن را ایجاد کرده و کد زیر را به آن اضافه میکنیم:
ما یک جدول بوتاسترپ React برای لیستبندی سندها به همراه دکمههایی برای ویرایش و حذف اسناد و تولید سند ورد داریم. ضمناً یک لینک Open برای باز کردن سند ورد در هر سطر وجود دارد. ما باید یک دکمه در ابتدای جدول ایجاد کنیم.
زمانی که صفحه بارگذاری میشود، getAllDocuments را فراخوانی کرده و موارد موجود را در استور MobX قرار میدهیم. کادرهای محاورهای add و edit را با تابعهای openAddTemplateModal, closeAddModal, cancelAddModal و cancelEditModal باز و بسته میکنیم. سپس فایل request.js را در پوشه src ایجاد کرده و کد زیر را به آن اضافه میکنیم:
کد فوق تابعهایی برای ایجاد درخواست به مسیرهای موجود در بکاند اضافه میکند. سپس استور MobX را ایجاد میکنیم. به این منظور فایل store.js را در پوشه src ایجاد کرده و کد زیر را در آن قرار میدهیم:
ما تابع setDocuments را برای قرار دادن دادههای عکس در استور داریم که در HomePage و DocumentForm استفاده شده است و آن را پیش از اکسپورت کردن وهلهسازی میکنیم. به این ترتیب میتوانیم این کار را تنها در یک مکان انجام دهیم. بلوک کد زیر به آرایه documents در DocumentStore اختصاص دارد که به عنوان مدخلی است که میتواند از سوی کامپوننتها تحت نظر قرار گیرد تا به تغییرها واکنش نشان دهند. تابع setDocuments به عنوان تابعی است که میتواند برای تعیین آرایه documents در store مورد استفاده قرار گیرد:
سپس نوار فوقانی را با ایجاد فایل TopBar.js در پوشه src ایجاد کرده و کد زیر را به آن اضافه میکنیم:
این فایل شامل Navbar بوتاسترپ ریاکت برای نمایش نوار فوقانی به همراه لینکی به صفحه اصلی و نام اپلیکیشن است. ما آن را تنها زمانی نمایش میدهیم که token در local storage موجود باشد. pathname را بررسی میکنیم تا لینکهای صحیح را با تعیین prop به نام active هایلایت کنیم. سپس در فایل index.html کد موجود را با کد زیر عوض میکنیم:
این کد CSS بوتاسترپ را اضافه میکند و عنوان را تغییر میدهد. پس از نوشتن همه این کدها میتوانیم اپلیکیشن خود را اجرا کنیم. پیش از اجرای اپلیکیشن باید nodemon را با اجرای دستور زیر نصب کنیم تا مجبور نباشیم در زمان تغییر یافتن فایلها، بکاند را به صورت دستی ریاستارت کنیم:
npm i -g nodemon
سپس بکاند را با اجرای دستور npm start در پوشه backend و دستور npm start در پوشه frontend فعال کنید و در ادامه اگر در مورد اجرای آن از پورت متفاوت سؤال شود، گزینه yes را انتخاب کنید. در نهایت اپلیکیشنی مانند تصاویر زیر به دست میآوریم:
بدین ترتیب به پایان این مقاله رسیدیم. اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای JavaScript (جاوا اسکریپت)
- مجموعه آموزشهای برنامهنویسی
- استریم و بافر در Node.js — به زبان ساده
- آموزش Node.js: آشنایی با استریم ها و کار با MySQL — بخش دوازدهم
- استفاده از الگوی طراحی سلکتور در Node.js — از صفر تا صد
==