1+ import { exec } from 'child_process' ;
2+ import fs from 'fs' ;
3+ import path from 'path' ;
4+ import { promisify } from 'util' ;
5+ import { v4 as uuidv4 } from 'uuid' ;
6+ import os from 'os' ;
7+
8+ const execPromise = promisify ( exec ) ;
9+
110/**
211 * Service for generating Word documents from HTML content
312 */
413export const docService = {
514 /**
6- * Generate a Word document from HTML content
15+ * Generate a Word document from HTML content using pandoc
716 * @param {string } html - The HTML content to convert to Word format
8- * @returns {Buffer } - A buffer containing the Word document data
17+ * @returns {Promise< Buffer> } - A buffer containing the Word document data
918 */
10- generateDoc ( html ) {
11- // Create Word document from HTML
12- const header = `
13- <html xmlns:o='urn:schemas-microsoft-com:office:office'
14- xmlns:w='urn:schemas-microsoft-com:office:word'
15- xmlns='http://www.w3.org/TR/REC-html40'>
16- <head><meta charset='utf-8'></head><body>` ;
17- const footer = `</body></html>` ;
18- const sourceHTML = header + html + footer ;
19-
20- // Add BOM (Byte Order Mark) for proper encoding in Word
21- const bomPrefix = Buffer . from ( [ 0xEF , 0xBB , 0xBF ] ) ;
22- const htmlBuffer = Buffer . from ( sourceHTML ) ;
23- const docBuffer = Buffer . concat ( [ bomPrefix , htmlBuffer ] ) ;
24-
25- return docBuffer ;
19+ async generateDoc ( html ) {
20+ try {
21+ // Create temporary files for input and output
22+ const tempDir = os . tmpdir ( ) ;
23+ const inputId = uuidv4 ( ) ;
24+ const outputId = uuidv4 ( ) ;
25+ const inputPath = path . join ( tempDir , `${ inputId } .html` ) ;
26+ const outputPath = path . join ( tempDir , `${ outputId } .docx` ) ;
27+
28+ // Write HTML to temporary file
29+ await fs . promises . writeFile ( inputPath , html , 'utf8' ) ;
30+
31+ // Use pandoc to convert HTML to DOCX
32+ const command = `pandoc -f html -t docx "${ inputPath } " -o "${ outputPath } "` ;
33+ console . log ( `Executing pandoc command: ${ command } ` ) ;
34+
35+ await execPromise ( command ) ;
36+
37+ // Read the generated DOCX file
38+ const docBuffer = await fs . promises . readFile ( outputPath ) ;
39+
40+ // Clean up temporary files
41+ try {
42+ await fs . promises . unlink ( inputPath ) ;
43+ await fs . promises . unlink ( outputPath ) ;
44+ } catch ( cleanupError ) {
45+ console . warn ( 'Error cleaning up temporary files:' , cleanupError ) ;
46+ }
47+
48+ return docBuffer ;
49+ } catch ( error ) {
50+ console . error ( 'Error generating Word document with pandoc:' , error ) ;
51+
52+ // If pandoc fails, provide a detailed error message
53+ if ( error . stderr ) {
54+ console . error ( 'Pandoc error output:' , error . stderr ) ;
55+ }
56+
57+ throw new Error ( `Failed to generate Word document: ${ error . message } ` ) ;
58+ }
2659 }
2760} ;
0 commit comments