Browse Source

feat: merge pdf from url to file

ryanemax 7 months ago
parent
commit
29de49ced3
4 changed files with 859 additions and 21 deletions
  1. 41 5
      server/cloud/tbook/func-tbook-export.js
  2. 43 9
      server/lib/docs/index.js
  3. 774 7
      server/package-lock.json
  4. 1 0
      server/package.json

+ 41 - 5
server/cloud/tbook/func-tbook-export.js

@@ -79,8 +79,9 @@ export async function exportProcessReportDocs(processId,bookList) {
     let zipPath,zipUrl
     if(docsList?.length){
         let now = new Date();
+        let fileList = docsList?.map(item=>item?.pdfPath);
         let zipName = `申报书导出-${now.getFullYear()}${now.getMonth()+1}${now.getDate()}-${now.getHours()}${now.getMinutes()}${now.getSeconds()}.zip`
-        zipPath = await createZip(docsList?.map(item=>item?.filePath),zipName)
+        zipPath = await createZip(fileList,zipName)
         if(zipPath){
             zipUrl = (await uploadFileToOSS(zipPath))?.url || null
         }
@@ -165,6 +166,35 @@ function renderReportDocsByTextbook(textbook){
         clist[index] = [num,toYearMonth(json?.courses?.[index]?.date)||" ",json?.courses?.[index]?.wordage||" ",json?.courses?.[index]?.num||" ",json?.courses?.[index]?.sumNum||" ",json?.courses?.[index]?.accolade||" "]
     }
     
+    // 附件信息
+    let mergeFiles = []
+    // 1.教材电子版(必须提供)
+    // (教材出版单位配合按要求上传各地推荐的本单位出版的纸质教材最新印次的完整PDF电子版;数字教材上传全部教材内容电子版或填写能够查看全部教材内容的链接地址、账号;纸质教材附带数字资源的,上传纸质教材最新印次的完整PDF电子版,以及全部数字资源电子版或能够查看全部数字资源内容的链接地址、账号。)
+    // 2.所有作者政治审查意见(必须提供)
+    // (对应作者姓名上传“作者政治审查表”。作者单位党委对作者进行审查,对政治思想表现情况进行评价,确保作者的正确政治方向、价值取向,无违法违纪等记录。教材编写成员涉及多个不同单位时需要各单位分别出具意见,并由所在单位党委盖章,格式要求从申报平台下载。)
+    // 3.图书编校质量自查结果记录表(必须提供)
+    // (教材出版单位对申报教材的编校质量自查后,按要求提供图书编校质量自查结果记录表,并加盖出版社公章。全册教材的不同分册以不同文件分别上传。格式要求从申报平台下载。)
+    if(json?.selfResults?.url){mergeFiles.push(json?.selfResults?.url)}
+    // 4.专家审查意见表(必须提供)
+    // (由第一主编所在单位和出版机构邀请校内外相关学科专业领域专家,对教材进行思想性、学术性审查。专家不少于3名,其中半数以上为校外专家,专家分别实名评价并签字,并注明所在单位及专业身份。评价人不得是本教材的作者。)
+    if(json?.expertOpinion?.url){mergeFiles.push(json?.expertOpinion?.url)}
+    // 5.教材使用情况证明材料(必须提供)
+    // (教材出版单位提供教材主要使用高校名单及使用情况证明材料,并加盖公章。)
+    if(json?.evidence?.url){mergeFiles.push(json?.evidence?.url)}
+    // 6.版权信息及CIP数据(必须提供)
+    // (版权页截图,中国版本图书馆CIP查询截图,如CIP数据中无“教材”字样的,须再上传内容提要或前言或后记中可以证明本书为教材的相关内容截图。)
+    if(json?.CIPImgUrl){mergeFiles.push(json?.CIPImgUrl)}
+    // 7.其他材料(可选提供)
+    if(json?.moreMaterial?.length){
+        json?.moreMaterial.forEach(doc=>{
+            if(doc?.url){
+                mergeFiles.push(doc?.url)
+            }
+        })
+    }
+
+    // (其他佐证材料,限两份以内。)
+
     let fixData = {
         // 封面信息
         titlePad:padString(json?.title,21),
@@ -257,7 +287,7 @@ function renderReportDocsByTextbook(textbook){
     Object.keys(fixData).forEach(key=>{
         bookData[key] = fixData[key]
     })
-    console.log(bookData)
+    // console.log(bookData)
     // console.log(json)
     let bookid = json.code || json?.objectId;
     let tempFileName = path.join(`${bookid}${json.title}.docx`)
@@ -265,13 +295,19 @@ function renderReportDocsByTextbook(textbook){
         let filePath = renderDocx(TemplateDocxPath,tempFileName,bookData)
         // 需要API支持
         let pdfPath = filePath.replaceAll(".docx",".pdf")
-        filePath = await docxToPdf(filePath,pdfPath) || filePath // 成功用pdf,失败继续用docx
-        let url = (await uploadFileToOSS(pdfPath))?.url || null
+        let options = {
+            mergeFiles:mergeFiles
+        }
+        pdfPath = await docxToPdf(filePath,pdfPath,options) || filePath // 成功用pdf,失败继续用docx
+        let urlDocx = (await uploadFileToOSS(filePath))?.url || null
+        let urlPdf = (await uploadFileToOSS(pdfPath))?.url || null
         resolve({
             code:bookid,
             title:json?.title,
             filePath,
-            url
+            pdfPath,
+            urlDocx,
+            urlPdf,
         })
         return
         replaceDocx(TemplateDocxPath,tempFileName,bookData,{onDocxComplete:async (filePath)=>{

+ 43 - 9
server/lib/docs/index.js

@@ -73,13 +73,13 @@ module.exports.uploadFileToOSS = uploadFileToOSS
             const output = fs.createWriteStream(outputPath);
             
             // 使用 compressing 库的 zip 方法将文件打包
-            console.log(filePathList)
+            // console.log(filePathList)
             // await compressing.zip.compressDir(filePathList, output);
             // 将zip流写入文件
             zipStream.pipe(output);
 
             output.on('finish', () => {
-                console.log(`成功创建压缩包: ${outputPath}`);
+                // console.log(`成功创建压缩包: ${outputPath}`);
                 resolve(outputPath)
             });
 
@@ -99,6 +99,23 @@ module.exports.uploadFileToOSS = uploadFileToOSS
 }
 module.exports.createZip = createZip
 
+
+const download = require('download')
+async function downloadUrl(url) {
+    let filename = path.basename(url)
+    let filepath = path.join(tempDir,filename)
+    // console.log(filename,filepath)
+    try{
+        if(fs.existsSync(filepath)){fs.rmSync(filepath)}
+        fs.writeFileSync(filepath, await download(url));
+        return filepath
+    }catch(err){
+        console.error(err)
+        return null
+    }
+}
+
+
 /**
  * 将 DOCX 文件转换为 PDF
  * 
@@ -106,15 +123,32 @@ module.exports.createZip = createZip
  * @param {string} outputPath - 输出 PDF 文件的路径
  * @returns {Promise<void>}
  */
- export async function docxToPdf(docxPath, outputPath) {
+ export async function docxToPdf(docxPath, outputPath,options) {
+    let mergeFiles = options?.mergeFiles || []
+    let filePathList = []
+    let merge = false;
+    if(mergeFiles?.length){
+        for (let index = 0; index < mergeFiles.length; index++) {
+            let filePath
+            try{
+                filePath = await downloadUrl(mergeFiles[index]);
+            }catch(err){}
+            if(filePath){
+                filePathList.push(filePath)
+            }
+        }
+        merge = true;
+    }
+
     try {
         let docxBuffer = fs.readFileSync(docxPath);
 
         let files = [
             // docxPath
             { data: docxBuffer, ext: "docx" },
+            ...filePathList
         ];
-        console.log(files)
+        // console.log(files)
         let pdfBuffer = await LibreOffice.convert({
             files,
             properties: {
@@ -122,15 +156,15 @@ module.exports.createZip = createZip
                 pageSize: 'A4',
                 orientation: 'portrait',
                 margin: {
-                    top: 10,
-                    right: 10,
-                    bottom: 10,
-                    left: 10
+                    top: 0,
+                    right: 0,
+                    bottom: 0,
+                    left: 0
                 }
             },
             pdfa: false, // 根据需要设置
             pdfUA: false, // 根据需要设置
-            merge: false, // 如果只转换一个文件,设置为false
+            merge: merge, // 如果只转换一个文件,设置为false
             // metadata: {
             //     // 你可以在这里添加元数据
             // },

File diff suppressed because it is too large
+ 774 - 7
server/package-lock.json


+ 1 - 0
server/package.json

@@ -35,6 +35,7 @@
     "chromiumly": "^3.6.0",
     "compressing": "^1.10.1",
     "docxtemplater": "^3.49.1",
+    "download": "^8.0.0",
     "node-schedule": "^2.1.1",
     "parse-dashboard": "^5.4.0",
     "parse-server": "^7.0.0",

Some files were not shown because too many files changed in this diff