wkplhc commited on
Commit
f7d32af
·
verified ·
1 Parent(s): a3c8253

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +144 -0
server.js CHANGED
@@ -227,6 +227,150 @@ app.post('/api/parse-character-png', upload.single('file'), async (req, res) =>
227
  }
228
  });
229
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
230
  const PORT = process.env.PORT || 7860;
231
 
232
  app.listen(PORT, () => {
 
227
  }
228
  });
229
 
230
+ // PDF生成API
231
+ app.post('/api/generate-pdf', async (req, res) => {
232
+ try {
233
+ const { title, chapters, style } = req.body;
234
+
235
+ if (!title || !chapters) {
236
+ return res.status(400).json({ error: '缺少必要参数' });
237
+ }
238
+
239
+ // 导入必要的库
240
+ const { default: PDFDocument } = await import('pdfkit');
241
+ const { default: fetch } = await import('node-fetch');
242
+
243
+ // 创建PDF文档
244
+ const doc = new PDFDocument({
245
+ size: 'A4',
246
+ margins: { top: 50, bottom: 50, left: 50, right: 50 }
247
+ });
248
+
249
+ // 设置响应头
250
+ res.setHeader('Content-Type', 'application/pdf');
251
+ res.setHeader('Content-Disposition', `attachment; filename="${encodeURIComponent(title)}.pdf"`);
252
+
253
+ // 管道输出到响应
254
+ doc.pipe(res);
255
+
256
+ // 样式配置
257
+ const styles = {
258
+ modern: {
259
+ titleFont: 'Helvetica-Bold',
260
+ titleSize: 32,
261
+ headingFont: 'Helvetica-Bold',
262
+ headingSize: 20,
263
+ bodyFont: 'Helvetica',
264
+ bodySize: 12,
265
+ lineHeight: 1.5
266
+ },
267
+ classic: {
268
+ titleFont: 'Times-Bold',
269
+ titleSize: 36,
270
+ headingFont: 'Times-Bold',
271
+ headingSize: 22,
272
+ bodyFont: 'Times-Roman',
273
+ bodySize: 13,
274
+ lineHeight: 1.6
275
+ },
276
+ magazine: {
277
+ titleFont: 'Helvetica-Bold',
278
+ titleSize: 40,
279
+ headingFont: 'Helvetica-Bold',
280
+ headingSize: 24,
281
+ bodyFont: 'Helvetica',
282
+ bodySize: 11,
283
+ lineHeight: 1.4
284
+ },
285
+ technical: {
286
+ titleFont: 'Courier-Bold',
287
+ titleSize: 28,
288
+ headingFont: 'Courier-Bold',
289
+ headingSize: 18,
290
+ bodyFont: 'Courier',
291
+ bodySize: 10,
292
+ lineHeight: 1.5
293
+ }
294
+ };
295
+
296
+ const currentStyle = styles[style] || styles.modern;
297
+
298
+ // 封面
299
+ doc.font(currentStyle.titleFont)
300
+ .fontSize(currentStyle.titleSize)
301
+ .text(title, 50, 300, { align: 'center' });
302
+
303
+ doc.fontSize(14)
304
+ .font('Helvetica')
305
+ .text(`生成于 ${new Date().toLocaleDateString('zh-CN')}`, 50, 400, { align: 'center' });
306
+
307
+ doc.addPage();
308
+
309
+ // 生成章节
310
+ for (let i = 0; i < chapters.length; i++) {
311
+ const chapter = chapters[i];
312
+
313
+ // 章节标题
314
+ if (i > 0) {
315
+ doc.addPage();
316
+ }
317
+
318
+ doc.font(currentStyle.headingFont)
319
+ .fontSize(currentStyle.headingSize)
320
+ .text(chapter.title, { align: 'left' });
321
+
322
+ doc.moveDown(1);
323
+
324
+ // 章节内容
325
+ doc.font(currentStyle.bodyFont)
326
+ .fontSize(currentStyle.bodySize);
327
+
328
+ // 移除IMAGE标记
329
+ const cleanContent = chapter.content.replace(/\[IMAGE:.*?\]/g, '');
330
+ const paragraphs = cleanContent.split('\n').filter(p => p.trim());
331
+
332
+ for (const paragraph of paragraphs) {
333
+ doc.text(paragraph, {
334
+ align: 'justify',
335
+ lineGap: currentStyle.lineHeight * 2
336
+ });
337
+ doc.moveDown(0.5);
338
+ }
339
+
340
+ // 插入图片
341
+ if (chapter.images && chapter.images.length > 0) {
342
+ for (const imageUrl of chapter.images) {
343
+ try {
344
+ // 下载图片
345
+ const imageResponse = await fetch(imageUrl);
346
+ const imageBuffer = await imageResponse.buffer();
347
+
348
+ doc.moveDown(1);
349
+
350
+ // 添加图片(适配页面宽度)
351
+ const pageWidth = doc.page.width - 100;
352
+ doc.image(imageBuffer, 50, doc.y, {
353
+ fit: [pageWidth, 300],
354
+ align: 'center'
355
+ });
356
+
357
+ doc.moveDown(1);
358
+ } catch (error) {
359
+ console.error('添加图片失败:', error);
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ // 完成PDF
366
+ doc.end();
367
+
368
+ } catch (error) {
369
+ console.error('PDF生成错误:', error);
370
+ res.status(500).json({ error: error.message });
371
+ }
372
+ });
373
+
374
  const PORT = process.env.PORT || 7860;
375
 
376
  app.listen(PORT, () => {