MAISON CODE .
/ Backend · React · PDF · Serverless · Automation

إنشاء ملفات PDF الديناميكية: هندسة الورق الرقمي

كيفية إنشاء ملفات PDF عالية الدقة (الفواتير والتذاكر) باستخدام React وNode.js. مقارنة بين @react-pdf/renderer وPuppeteer في البيئات التي لا تحتوي على خادم.

AB
Alex B.
إنشاء ملفات PDF الديناميكية: هندسة الورق الرقمي

العالم يعمل على HTML، ولكن الأعمال التجارية تعمل على PDF. طلب التجارة الإلكترونية ليس “حقيقيًا” حتى تكون هناك فاتورة. لا تكون تذكرة الحفل “صالحة” حتى يكون هناك رمز QR على ملف PDF. لسنوات، كان إنشاء ملفات PDF هو المهمة الأكثر كرهًا في تطوير الواجهة الخلفية. لقد تضمنت أدوات قديمة مثل wkhtmltopdf أو قوالب XML أو نصوص Python الهشة.

في Maison Code Paris، ننقل إنشاء ملفات PDF إلى العصر الحديث. نحن نستخدم نفس بنية المكونات (React) لمستنداتنا كما نستخدمها لواجهات المستخدم الخاصة بنا. وهذا يضمن أن اتساق العلامة التجارية مطلق. الخط الموجود على الموقع هو الخط الموجود في الفاتورة.

لماذا يناقش Maison Code هذا الأمر

في Maison Code Paris، نعمل بمثابة الضمير المعماري لعملائنا. غالبًا ما نرث الأكوام “الحديثة” التي تم إنشاؤها دون فهم أساسي للحجم. نرى واجهات برمجة تطبيقات بسيطة تستغرق 4 ثوانٍ للرد بسبب مشكلات استعلام N+1، و”الخدمات الصغيرة” التي تكلف 5000 دولار شهريًا كرسوم سحابية خاملة.

نناقش هذا الموضوع لأنه يمثل نقطة محورية حاسمة في النضج الهندسي. إن تنفيذ هذا بشكل صحيح يميز MVP الهش عن النظام الأساسي المرن على مستوى المؤسسات والذي يمكنه التعامل مع حركة مرور الجمعة السوداء دون بذل أي جهد.

المناظر الطبيعية: كيفية تقديم ملف PDF

هناك ثلاث طرق رئيسية لإنشاء ملف PDF اليوم، ولكل منها مقايضات ضخمة.

النهجالأدواتالايجابياتسلبيات
بدون متصفح (كروم بلا رأس)محرك الدمى، كاتب مسرحيدعم CSS مثالي للبيكسل. إذا كان بإمكانك بنائه بتنسيق HTML، فيمكنك طباعته.بطيء. استخدام الذاكرة الثقيلة. يتطلب تشغيل مثيل متصفح (Chromium) وهو أمر مؤلم في بدون خادم.
بدائيات PDFPDFKit، jsPDFسريع للغاية. التبعيات صفر.** المطور ح ***. يجب عليك رسم الخطوط يدويًا (doc.moveTo(100, 100).lineTo(200, 200)). الحفاظ على التخطيطات هو كابوس.
React-PDF / @react-pdf/rendererرد فعل فليكس بوكس ​​الكأس المقدسة. اكتب مكونات React واحصل على ملف PDF. سريع بما فيه الكفاية.مجموعة CSS الفرعية فقط (Flexbox بشكل رئيسي). لا يوجد دعم للشبكة حتى الآن.

في Maison Code، نقوم بتوحيد معايير React-PDF بشكل صارم.

الهندسة المعمارية: لماذا يفوز React-PDF

يعد تغيير النموذج الذهني أمرًا بسيطًا: ملف PDF هو مجرد هدف عرض آخر. تمامًا مثل عرض ReactDOM إلى DOM، وعرض ReactNative لعروض iOS/Android، يعرض @react-pdf/renderer إلى مواصفات PDF.

1. مشاركة التعليمات البرمجية

يمكنك مشاركة أنواع الرموز المميزة لنظام التصميم الخاص بك.

استيراد {StyleSheet} من '@react-pdf/renderer'؛
استيراد {الموضوع} من '@/design-system/theme'؛

أنماط ثابتة = StyleSheet.create({
  رأس: {
    FontFamily: theme.fonts.heading، // "Bodoni Moda"
    اللون: theme.colors.void، // #000000
    حجم الخط: 24،
  }
});

وهذا يضمن أن فاتورتك تتطابق مع صفحة الدفع الخاصة بك بكسلًا مقابل بكسل.

2. عمليات التشغيل الباردة بدون خادم

يعد تشغيل Puppeteer على AWS Lambda بمثابة معركة مستمرة ضد حد الحزمة البالغ 50 ميجابايت وبدء التشغيل البارد لمدة 10 ثوانٍ. React-PDF هي مجرد مكتبة Node.js. إنه يضيف بشكل فعال 0 مللي ثانية إلى بدايتك الباردة. يقوم بتجميع السلاسل إلى المخازن المؤقتة الثنائية. إنه مرتبط بوحدة المعالجة المركزية (CPU)، وليس مرتبطًا بالإدخال/الإخراج.

التنفيذ: مكون “الورق الرقمي”.

فيما يلي مثال حقيقي لمكون الفاتورة.

استيراد {مستند، صفحة، نص، عرض، ورقة الأنماط، الخط} من '@react-pdf/renderer'؛

// تسجيل الخطوط المخصصة (مهم للعلامة التجارية)
تسجيل الخط({
  العائلة: "بودوني مودا"،
  src: "https://cdn.maisoncode.paris/fonts/BodoniModa-Regular.ttf"
});

فاتورة ثابتة = ({ الطلب }) => (
  <المستند>
    <حجم الصفحة = "A4" style={styles.page}>
      
      {/* العنوان * /}
      <عرض النمط={styles.header}>
        <Text style={styles.brand}>رمز الدار.</Text>
        <Text style={styles.invoiceId}>INV-{order.id}</Text>
      </عرض>

{/* العناصر * /}
      <عرض النمط={styles.table}>
        {order.items.map(العنصر => (
          <عرض النمط={styles.row}>
            <نمط النص={styles.cellDesc}>{item.name}</Text>
            <Text style={styles.cellQty}>x{item.quantity}</Text>
            <نمط النص={styles.cellTotal}>€{item.price}</Text>
          </عرض>
        ))}
      </عرض>

      {/* التذييل * /}
      <عرض النمط={styles.footer}>
         <نص>شكرًا لك على عملك. هذه الوثيقة هي نسخة رقمية أصلية.</Text>
      </عرض>

    </الصفحة>
  </وثيقة>
);

نقطة نهاية واجهة برمجة التطبيقات

لا تقم بحفظ الملفات على القرص. يمكنك دفقها مباشرة إلى العميل أو S3.

// مسار Next.js / Node.js API
استيراد { renderToStream } من '@react-pdf/renderer'؛

تصدير وظيفة غير متزامنة POST(req) {
  تيار ثابت = انتظار renderToStream(<Invoice order={req.body} />);
  
  إرجاع استجابة جديدة (دفق، {
    رؤوس: {
      "نوع المحتوى": "application/pdf"،
      "التصرف في المحتوى": "مرفق؛ اسم الملف = "invoice.pdf"'
    }
  });
}

الأداء: قاعدة الـ 500 مللي ثانية

في التجارة الإلكترونية، إذا دار زر “تنزيل الفاتورة” لمدة 5 ثوانٍ، فإن المستخدم يفترض أن الموقع معطل. يستغرق محرك الدمى من 3 إلى 8 ثوانٍ للتمهيد والتنقل والطباعة. يستغرق React-PDF 200ms-600ms لتقديم فاتورة معقدة.

يتيح لك هذا الاختلاف في السرعة إنشاء ملفات PDF بشكل متزامن عند الطلب، بدلاً من وضعها في قائمة الانتظار في مهمة خلفية (Celery/SQS) وإرسالها بالبريد الإلكتروني لاحقًا. جزء واحد أقل متحركة. قائمة انتظار أقل للمراقبة.

الخلاصة

توقف عن التعامل مع ملفات PDF كمواطنين من الدرجة الثانية. من خلال اعتماد React-PDF، يمكنك إدخال طبقة المستند في سير العمل الهندسي القياسي لديك.

  • التحكم في الإصدار: يتم تتبع قوالب الفاتورة الخاصة بك عن طريق البوابة.
  • أمان النوع: يفشل إنشاء ملف PDF الخاص بك في وقت الإنشاء إذا فاتك حقل “السعر”.
  • اتساق التصميم: تظل علامتك التجارية متميزة، حتى على الورق.

في قطاع المنتجات الفاخرة، تعتبر تجربة ما بعد الشراء لا تقل أهمية عن البيع. الفاتورة الجميلة والفورية هي اللمسة النهائية لمعاملة متميزة.


قم بتعيين مهندسينا المعماريين لتدقيق مسار إنشاء المستندات لديك.