FileController.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. using DocumentFormat.OpenXml.Packaging;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Configuration;
  5. using PdfSharpCore.Pdf;
  6. using PdfSharpCore.Pdf.IO;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Diagnostics;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Threading.Tasks;
  13. using System.Xml;
  14. using System.Xml.Linq;
  15. using TEAMModelOS.SDK.Context.Configuration;
  16. using TEAMModelOS.SDK.Context.Constant;
  17. using TEAMModelOS.SDK.Context.Constant.Common;
  18. using TEAMModelOS.SDK.Context.Exception;
  19. using TEAMModelOS.SDK.Extension.DataResult.JsonRpcRequest;
  20. using TEAMModelOS.SDK.Extension.DataResult.JsonRpcResponse;
  21. using TEAMModelOS.SDK.Helper.Common.StringHelper;
  22. using TEAMModelOS.SDK.Helper.Security.ShaHash;
  23. using TEAMModelOS.SDK.Module.AzureBlob.Container;
  24. namespace HiTeachCE.Controllers
  25. {
  26. [Route("api/[controller]")]
  27. [ApiController]
  28. public class FileController
  29. {
  30. static XmlNamespaceManager xmlnsManager;
  31. static FileController()
  32. {
  33. xmlnsManager = new XmlNamespaceManager(new NameTable());
  34. xmlnsManager.AddNamespace("p", "http://schemas.openxmlformats.org/presentationml/2006/main");
  35. xmlnsManager.AddNamespace("a", "http://schemas.openxmlformats.org/drawingml/2006/main");
  36. xmlnsManager.AddNamespace("xsl", "http://www.w3.org/1999/XSL/Transform");
  37. xmlnsManager.AddNamespace("fo", "http://www.w3.org/1999/XSL/Format");
  38. xmlnsManager.AddNamespace("app", "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties");
  39. xmlnsManager.AddNamespace("cp", "http://schemas.openxmlformats.org/package/2006/metadata/core-properties");
  40. xmlnsManager.AddNamespace("dc", "http://purl.org/dc/elements/1.1/");
  41. xmlnsManager.AddNamespace("dcterms", "http://purl.org/dc/terms/");
  42. xmlnsManager.AddNamespace("dcmitype", "http://purl.org/dc/dcmitype/");
  43. xmlnsManager.AddNamespace("rel", "http://schemas.openxmlformats.org/package/2006/relationships");
  44. xmlnsManager.AddNamespace("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
  45. xmlnsManager.AddNamespace("cus", "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties");
  46. xmlnsManager.AddNamespace("vt", "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes");
  47. xmlnsManager.AddNamespace("pic", "http://schemas.openxmlformats.org/drawingml/2006/picture");
  48. xmlnsManager.AddNamespace("dsp", "http://schemas.microsoft.com/office/drawing/2008/diagram");
  49. xmlnsManager.AddNamespace("dgm", "http://schemas.openxmlformats.org/drawingml/2006/diagram");
  50. xmlnsManager.AddNamespace("a14", "http://schemas.microsoft.com/office/drawing/2010/main");
  51. xmlnsManager.AddNamespace("m", "http://schemas.openxmlformats.org/officeDocument/2006/math");
  52. xmlnsManager.AddNamespace("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
  53. xmlnsManager.AddNamespace("p14", "http://schemas.microsoft.com/office/powerpoint/2010/main");
  54. xmlnsManager.AddNamespace("pkg", "http://schemas.microsoft.com/office/2006/xmlPackage");
  55. xmlnsManager.AddNamespace("p15", "http://schemas.microsoft.com/office/powerpoint/2012/main");
  56. xmlnsManager.AddNamespace("a16", "http://schemas.microsoft.com/office/drawing/2014/main");
  57. xmlnsManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
  58. xmlnsManager.AddNamespace("c", "http://schemas.openxmlformats.org/drawingml/2006/chart");
  59. xmlnsManager.AddNamespace("c14", "http://schemas.microsoft.com/office/drawing/2007/8/2/chart");
  60. xmlnsManager.AddNamespace("c16", "http://schemas.microsoft.com/office/drawing/2014/chart");
  61. xmlnsManager.AddNamespace("cs", "http://schemas.microsoft.com/office/drawing/2012/chartStyle");
  62. xmlnsManager.AddNamespace("thm15", "http://schemas.microsoft.com/office/thememl/2012/main");
  63. xmlnsManager.AddNamespace("fn", "http://www.w3.org/2005/xpath-functions");
  64. }
  65. /// <summary>
  66. /// </summary>
  67. /// <param name="request"></param>
  68. /// <returns></returns>
  69. [HttpPost("upload")]
  70. [RequestSizeLimit(102_400_000_00)] //最大10000m左右
  71. public async Task<BaseJosnRPCResponse> upload([FromForm] IFormFile file)
  72. {
  73. //if (!IsImage(file.OpenReadStream())) {
  74. // throw new BizException("请上传图片类型的文件!", 2);
  75. //}
  76. JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
  77. string filname = ShaHashHelper.GetSHA1(file.OpenReadStream());
  78. string extension = System.IO.Path.GetExtension(file.FileName).ToLower();
  79. // Dictionary<string, object> model = await fileService.UploadDocument(file);
  80. string path = BaseConfigModel.ContentRootPath + "/Avatar/" + filname + extension;
  81. if (System.IO.File.Exists(path) == false)
  82. {
  83. using (var stream = new FileStream(path, FileMode.Create))
  84. {
  85. await file.CopyToAsync(stream);
  86. }
  87. }
  88. var url = "https://cdhabook.teammodel.cn/avatar/" + filname + extension;
  89. return responseBuilder.Data(url).build();
  90. }
  91. [HttpPost("uploadBase64")]
  92. public BaseJosnRPCResponse UploadBase64(JosnRPCRequest<string> files)
  93. {
  94. string filname = ShaHashHelper.GetSHA1(files.@params);
  95. JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
  96. string[] strs = files.@params.Split(',');
  97. string fileExt = StringHelper.SubMidString(strs[0], ":", ";");
  98. if (ContentTypeDict.extdict.TryGetValue(fileExt, out string ext))
  99. {
  100. fileExt = ext;
  101. }
  102. else
  103. {
  104. //解决多种扩展名不能获取的
  105. string[] sp = StringHelper.SubMidString(strs[0], "/", ";").Split("-");
  106. fileExt = sp[sp.Length - 1];
  107. sp = fileExt.Split("+");
  108. fileExt = "." + sp[sp.Length - 1];
  109. }
  110. string path = BaseConfigModel.ContentRootPath + "/Avatar/" + filname + fileExt;
  111. if (System.IO.File.Exists(path) == false)
  112. {
  113. FileStream fs = new FileStream(path, FileMode.Create);
  114. BinaryWriter bw = new BinaryWriter(fs);
  115. bw.Write(Convert.FromBase64String(strs[1]));
  116. bw.Close();
  117. fs.Close();
  118. }
  119. var url = "https://cdhabook.teammodel.cn/avatar/" + filname + fileExt;
  120. return responseBuilder.Data(url).build();
  121. }
  122. /// <summary>
  123. /// docUrl
  124. /// folder
  125. /// shaCode
  126. /// </summary>
  127. /// <param name="request"></param>
  128. /// <returns></returns>
  129. [HttpPost("uploadDocument")]
  130. [RequestSizeLimit(102_400_000_00)] //最大10000m左右
  131. public async Task<BaseJosnRPCResponse> UploadDocument([FromForm] IFormFile file)
  132. {
  133. Dictionary<string, object> resdict = new Dictionary<string, object>();
  134. string contentRootPath = BaseConfigModel.ContentRootPath;
  135. JsonRPCResponseBuilder responseBuilder = new JsonRPCResponseBuilder();
  136. XmlDocument xmlDocument = new XmlDocument();
  137. string path = contentRootPath + "/OfficeFile/";
  138. string filname = ShaHashHelper.GetSHA1(file.OpenReadStream());
  139. string extension = System.IO.Path.GetExtension(file.FileName).ToLower();
  140. if (extension.Equals(".ppt") || extension.Equals(".doc") || extension.Equals(".pptx") || extension.Equals(".docx"))
  141. {
  142. if (System.IO.File.Exists(path + filname + ".pdf") == false)
  143. {
  144. //Console.WriteLine(filname + " Not Exists!");
  145. //if (extension.Equals(".ppt") || extension.Equals(".doc") || extension.Equals(".pptx") || extension.Equals(".docx"))
  146. //{
  147. //}
  148. //else
  149. //{
  150. // throw new BizException("file type does not support!", 500);
  151. //}
  152. if (extension.Equals(".pptx"))
  153. {
  154. using (PresentationDocument presentationDocument = PresentationDocument.Open(file.OpenReadStream(), false))
  155. {
  156. if (presentationDocument == null)
  157. {
  158. throw new ArgumentNullException("presentationDocument");
  159. }
  160. XDocument xdoc = presentationDocument.ToFlatOpcDocument();
  161. xmlDocument.LoadXml(xdoc.ToString());
  162. XmlNodeList xmlNodeList = xmlDocument.SelectNodes(@"//mc:Fallback", xmlnsManager);
  163. foreach (XmlNode nodeChild in xmlNodeList)
  164. {
  165. nodeChild.ParentNode.RemoveChild(nodeChild);
  166. }
  167. XmlNodeList xmlNodeListMp4 = xmlDocument.SelectNodes(@"//pkg:part[@pkg:contentType='video/mp4']", xmlnsManager);
  168. XmlDocument document = new XmlDocument();
  169. foreach (XmlNode nodeChild in xmlNodeListMp4)
  170. {
  171. throw new BizException("Please delete the video!/请删除视频再重新上传!", 1001);
  172. }
  173. XmlNodeList xmlNodeListMp3 = xmlDocument.SelectNodes(@"//pkg:part[@pkg:contentType='audio/mpeg']", xmlnsManager);
  174. foreach (XmlNode nodeChild in xmlNodeListMp3)
  175. {
  176. throw new BizException("Please delete the audio!/请删除音频再重新上传!", 1001);
  177. }
  178. var node = xmlDocument.Clone().OuterXml;
  179. XDocument xdocs = XDocument.Parse(node);
  180. presentationDocument.Dispose();
  181. using (PresentationDocument presentationDocumen1t = PresentationDocument.FromFlatOpcDocument(xdocs))
  182. {
  183. presentationDocumen1t.SaveAs(path + filname + ".pptx");
  184. presentationDocumen1t.Dispose();
  185. }
  186. }
  187. OnWork(path + filname + ".pptx");
  188. }
  189. else
  190. {
  191. Stream sourceStream = file.OpenReadStream();
  192. OnWork(sourceStream, path + filname + extension);
  193. }
  194. }
  195. //else { Console.WriteLine(filname + " Exists!"); }
  196. }
  197. else if (extension.Equals(".pdf"))
  198. {
  199. if (System.IO.File.Exists(path + filname + ".pdf") == false)
  200. {
  201. //// pdf
  202. string pathpdf = path + filname + ".pdf";
  203. using (var stream = new FileStream(pathpdf, FileMode.Create))
  204. {
  205. await file.CopyToAsync(stream);
  206. }
  207. /////
  208. }
  209. }
  210. else {
  211. throw new BizException("不支持的文件类型!",2);
  212. }
  213. PdfDocument inputDocument = PdfSharpCore.Pdf.IO.PdfReader.Open(path + filname + ".pdf", PdfDocumentOpenMode.Import);
  214. int count = inputDocument.PageCount;
  215. int limit = BaseConfigModel.Configuration.GetSection("PDFLimit").Get<int>();
  216. if (count > limit)
  217. {
  218. throw new BizException("PDF file cannot exceed " + limit + " pages!", 500);
  219. }
  220. //await ProcessPDF(file, resdict);
  221. resdict.Add("page", count);
  222. resdict.Add("type", "pdf");
  223. resdict.Add("model", new AzureBlobModel()
  224. {
  225. Folder = "OfficeFile",
  226. Sha1Code = filname,
  227. BlobUrl = "https://cdhabook.teammodel.cn/pdf/" + filname + ".pdf",
  228. ContentType = "application/pdf",
  229. ContentDisposition = "form-data; name=\"file\"; filename=\"" + filname + ".pdf\"",
  230. Length = inputDocument.FileSize,
  231. Name = "file",
  232. FileName = filname + ".pdf",
  233. RealName = "OfficeFile/" + filname + ".pdf",
  234. UploadTime = DateTime.Now.ToUniversalTime().Ticks - 621355968000000000,
  235. Extension = "pdf"
  236. });
  237. return responseBuilder.Data(resdict).build();
  238. }
  239. private bool SaveToFile(Stream stream, string path)
  240. {
  241. try
  242. {
  243. byte[] sourceBuffer = new Byte[stream.Length];
  244. stream.Read(sourceBuffer, 0, sourceBuffer.Length);
  245. stream.Seek(0, SeekOrigin.Begin);
  246. using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
  247. {
  248. fs.Write(sourceBuffer, 0, sourceBuffer.Length);
  249. fs.Close();
  250. }
  251. }
  252. catch (Exception ex)
  253. {
  254. Console.WriteLine("读取PPT源文件到本地失败:" + ex.Message);
  255. return false;
  256. }
  257. return true;
  258. }
  259. public bool OnWork(Stream stream, string path)
  260. {
  261. string sourcePath = string.Empty;
  262. string destPath = string.Empty;
  263. try
  264. {
  265. //if (FileInfo == null)
  266. // return false;
  267. // Stream sourceStream = FileInfo.OpenReadStream();
  268. // string filename = FileInfo.FileName;
  269. // string extension = System.IO.Path.GetExtension(FileInfo.FileName);
  270. // sourcePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename + extension);
  271. //destPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), string.Format("{0}.pdf", filename));
  272. if (!SaveToFile(stream, path))
  273. {
  274. return false;
  275. }
  276. var psi = new ProcessStartInfo("libreoffice", string.Format(" --headless --invisible --convert-to pdf {0} --outdir /www/apps/HiTeachCE/OfficeFile/", path)) { RedirectStandardOutput = true };
  277. Console.WriteLine(path);
  278. // psi = new ProcessStartInfo("pptx2pdf ", "/www/apps/pptx2pdf/OfficeFile/5e4df6b8-6fbf-4de0-9c94-8de4b5604e45.pptx") { RedirectStandardOutput = true };
  279. // 启动
  280. var proc = Process.Start(psi);
  281. if (proc == null)
  282. {
  283. Console.WriteLine("不能执行.");
  284. return false;
  285. }
  286. else
  287. {
  288. Console.WriteLine("-------------开始执行--------------");
  289. //开始读取
  290. using (var sr = proc.StandardOutput)
  291. {
  292. while (!sr.EndOfStream)
  293. {
  294. Console.WriteLine(sr.ReadLine());
  295. }
  296. if (!proc.HasExited)
  297. {
  298. proc.Kill();
  299. }
  300. }
  301. Console.WriteLine("---------------执行完成------------------");
  302. Console.WriteLine($"退出代码 : {proc.ExitCode}");
  303. }
  304. }
  305. catch (Exception ex)
  306. {
  307. Console.WriteLine(ex.Message);
  308. return false;
  309. }
  310. finally
  311. {
  312. //if (System.IO. File.Exists(destPath))
  313. //{
  314. // var destFileInfo = UploadFile(destPath, string.Format("{0}.pdf", Path.GetFileNameWithoutExtension( FileInfo.FileName)));
  315. //}
  316. //if (System.IO.File.Exists(destPath))
  317. //{
  318. // System.IO.File.Delete(destPath);
  319. //}
  320. }
  321. return true;
  322. }
  323. public bool OnWork(string path)
  324. {
  325. // string sourcePath = string.Empty;
  326. // string destPath = string.Empty;
  327. try
  328. {
  329. //if (FileInfo == null)
  330. // return false;
  331. // Stream sourceStream = FileInfo.OpenReadStream();
  332. // string filename = FileInfo.FileName;
  333. // string extension = System.IO.Path.GetExtension(FileInfo.FileName);
  334. // sourcePath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), filename + extension);
  335. //destPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), string.Format("{0}.pdf", filename));
  336. //if (!SaveToFile(sourceStream, sourcePath))
  337. // return false;
  338. var psi = new ProcessStartInfo("libreoffice", string.Format(" --headless --invisible --convert-to pdf {0} --outdir /www/apps/HiTeachCE/OfficeFile/", path)) { RedirectStandardOutput = true };
  339. Console.WriteLine(path);
  340. // psi = new ProcessStartInfo("pptx2pdf ", "/www/apps/pptx2pdf/OfficeFile/5e4df6b8-6fbf-4de0-9c94-8de4b5604e45.pptx") { RedirectStandardOutput = true };
  341. // 启动
  342. var proc = Process.Start(psi);
  343. if (proc == null)
  344. {
  345. Console.WriteLine("不能执行.");
  346. return false;
  347. }
  348. else
  349. {
  350. Console.WriteLine("-------------开始执行--------------");
  351. //开始读取
  352. using (var sr = proc.StandardOutput)
  353. {
  354. while (!sr.EndOfStream)
  355. {
  356. Console.WriteLine(sr.ReadLine());
  357. }
  358. if (!proc.HasExited)
  359. {
  360. proc.Kill();
  361. }
  362. }
  363. Console.WriteLine("---------------执行完成------------------");
  364. Console.WriteLine($"退出代码 : {proc.ExitCode}");
  365. }
  366. }
  367. catch (Exception ex)
  368. {
  369. Console.WriteLine(ex.Message);
  370. return false;
  371. }
  372. finally
  373. {
  374. //if (System.IO. File.Exists(destPath))
  375. //{
  376. // var destFileInfo = UploadFile(destPath, string.Format("{0}.pdf", Path.GetFileNameWithoutExtension( FileInfo.FileName)));
  377. //}
  378. //if (System.IO.File.Exists(destPath))
  379. //{
  380. // System.IO.File.Delete(destPath);
  381. //}
  382. }
  383. return true;
  384. }
  385. }
  386. }