You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

convert.js 5.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. const fs = require("fs");
  2. const path = require("path");
  3. const async = require("async");
  4. const { spawn } = require("child_process");
  5. function libreOffice(libreofficeBin, callback) {
  6. if (libreofficeBin) {
  7. return callback(null, libreofficeBin);
  8. } else {
  9. let paths = [];
  10. switch (process.platform) {
  11. case "darwin":
  12. paths = ["/Applications/LibreOffice.app/Contents/MacOS/soffice"];
  13. break;
  14. case "linux":
  15. paths = ["/usr/bin/libreoffice", "/usr/bin/soffice"];
  16. break;
  17. case "win32":
  18. paths = [
  19. path.join(
  20. process.env["PROGRAMFILES(X86)"],
  21. "LIBREO~1/program/soffice.exe"
  22. ),
  23. path.join(
  24. process.env["PROGRAMFILES(X86)"],
  25. "LibreOffice/program/soffice.exe"
  26. ),
  27. path.join(
  28. process.env.PROGRAMFILES,
  29. "LibreOffice/program/soffice.exe"
  30. ),
  31. ];
  32. break;
  33. default:
  34. return callback(
  35. new Error(
  36. `Operating system not yet supported to convert process: ${process.platform}`
  37. )
  38. );
  39. }
  40. return async.filter(
  41. paths,
  42. (filePath, callback) =>
  43. fs.access(filePath, (err) => callback(null, !err)),
  44. (err, res) => {
  45. if (res.length === 0) {
  46. return callback(new Error("Could not find soffice binary"));
  47. }
  48. return callback(
  49. null,
  50. process.platform === "win32" ? `${res[0]}` : res[0]
  51. );
  52. }
  53. );
  54. }
  55. }
  56. function parseCommand(librePath, cmd, convert) {
  57. let _args = [];
  58. if (process.platform === "win32" && convert === "pdf") {
  59. _args.push("/c");
  60. _args.push(librePath);
  61. }
  62. _args = _args.concat(cmd);
  63. return { _args };
  64. }
  65. function run(librePath, cmd, convert) {
  66. return new Promise((resolve, reject) => {
  67. const { _args } = parseCommand(librePath, cmd, convert);
  68. let _cmd = null;
  69. if (convert === "img") {
  70. _cmd = "convert";
  71. } else if (process.platform === "win32" && convert === "pdf") {
  72. _cmd = process.env.ComSpec;
  73. } else {
  74. _cmd = librePath;
  75. }
  76. const proc = spawn(_cmd, _args);
  77. proc.stdout.on("data", (data) => {
  78. // console.log("stdout", data.toString());
  79. });
  80. proc.stderr.on("error", function (err) {
  81. reject(err);
  82. });
  83. proc.on("close", (code) => {
  84. const status = code === 0 ? "Success" : "Error";
  85. resolve(status);
  86. });
  87. });
  88. }
  89. function pathExist(outputPath, callback) {
  90. fs.access(outputPath, fs.constants.F_OK, (err) => {
  91. if (err) {
  92. return callback(new Error("Source file does not exist."));
  93. }
  94. });
  95. }
  96. exports.convert = (
  97. { libreofficeBin, sourceFile, outputDir, img, imgExt, reSize, density },
  98. callback
  99. ) => {
  100. libreOffice(libreofficeBin, (err, res) => {
  101. if (err) {
  102. return err;
  103. } else {
  104. const baseFileName = path.basename(sourceFile);
  105. const outputFile = baseFileName.replace(/\.[^.]+$/, ".pdf");
  106. const outputImg = outputFile.replace(/\.pdf$/, `-%d.${imgExt || "png"}`);
  107. const ext = path.extname(sourceFile.toLowerCase());
  108. const extensions = [".pdf", ".pptx", ".ppt", ".odp", ".key"];
  109. const pdf = [
  110. "--headless",
  111. "--convert-to",
  112. "pdf",
  113. "--outdir",
  114. outputDir,
  115. sourceFile,
  116. ];
  117. const image = [
  118. "-verbose",
  119. "-resize",
  120. reSize || 1200,
  121. "-density",
  122. density || 120,
  123. `${outputDir}${outputFile}`,
  124. `${outputDir}${outputImg}`,
  125. ];
  126. const pdf2Img = [
  127. "-verbose",
  128. "-resize",
  129. reSize || 1200,
  130. "-density",
  131. density || 120,
  132. sourceFile,
  133. `${outputDir}${outputImg}`,
  134. ];
  135. if (ext === ".pdf")
  136. return run(res, pdf2Img, "img").then((res) => callback(null, res));
  137. fs.access(sourceFile, fs.constants.F_OK, (err) => {
  138. if (err) {
  139. return callback(new Error("Source file does not exist."));
  140. } else {
  141. if (extensions.includes(ext)) {
  142. run(res, pdf, "pdf")
  143. .then((pdfRes) => {
  144. if (pdfRes !== "Error") {
  145. if (!img) {
  146. return callback(null, pdfRes);
  147. } else {
  148. run(res, image, "img")
  149. .then((imageRes) => {
  150. if (imageRes !== "Error") {
  151. return callback(null, imageRes);
  152. } else {
  153. return callback(
  154. new Error("Error on image conversion process.")
  155. );
  156. }
  157. })
  158. .catch((e) => callback(e));
  159. }
  160. } else {
  161. return callback(
  162. new Error("Error on pdf conversion process.")
  163. );
  164. }
  165. })
  166. .catch((e) => callback(e));
  167. } else {
  168. return callback(new Error("Invalid extension."));
  169. }
  170. }
  171. });
  172. }
  173. });
  174. };