diff --git a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj index f932c782..c9f3963d 100644 --- a/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj +++ b/AsbCloudInfrastructure/AsbCloudInfrastructure.csproj @@ -35,9 +35,11 @@ + + diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ConvertToPdf.cs b/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ConvertToPdf.cs new file mode 100644 index 00000000..8233bd2b --- /dev/null +++ b/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ConvertToPdf.cs @@ -0,0 +1,66 @@ +using iTextSharp.text; +using iTextSharp.text.pdf; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using CliWrap; +using System.Threading.Tasks; + +namespace AsbCloudInfrastructure.Services.DrillingProgram.Convert +{ + internal class ConvertToPdf + { + private readonly string[] fileExtension = { ".xlsx", ".xls", ".ods", ".odt", ".doc", ".docx", ".pdf" }; + + public static void DoMergedAsync(IEnumerable inputFiles, string outFile) + { + using (FileStream stream = new FileStream(outFile, FileMode.Create)) + using (Document doc = new Document()) + using (PdfCopy pdf = new PdfCopy(doc, stream)) + { + doc.Open(); + PdfReader reader = null; + PdfImportedPage page = null; + inputFiles.ToList().ForEach(file => + { + reader = new PdfReader(file); + for (int i = 0; i < reader.NumberOfPages; i++) + { + page = pdf.GetImportedPage(reader, i + 1); + pdf.AddPage(page); + } + pdf.FreeReader(reader); + reader.Close(); + File.Delete(file); + }); + } + } + + private async Task StartConvertProcessAsync(string inputFileName, string outFileName) + { + var result = Cli.Wrap("/usr/bin/soffice") + .WithArguments($"--headless --convert-to pdf {inputFileName} --outdir {outFileName}"); + await result.ExecuteAsync(); + } + + public async Task GetConverteAndMergedFileAsync(IEnumerable filesNames, string resultPath) + { + var filteredFilesNames = filesNames + .Distinct() + .Where(f => fileExtension.Any(fe => f.ToLower().EndsWith(fe))) + .ToList(); + var listFileNames = filteredFilesNames + .ToList() + .Select(o => new { + inputFile = o, + convertedFile = Path.ChangeExtension(o, ".pdf") + }); + foreach (var fileName in listFileNames) + { + if (!fileName.inputFile.ToLower().EndsWith(".pdf")) + await StartConvertProcessAsync(fileName.inputFile, fileName.convertedFile); + } + DoMergedAsync(listFileNames.Select(c => c.convertedFile), resultPath); + } + } +} diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ReadMe.md b/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ReadMe.md new file mode 100644 index 00000000..e230682d --- /dev/null +++ b/AsbCloudInfrastructure/Services/DrillingProgram/Convert/ReadMe.md @@ -0,0 +1,19 @@ +КЛАСС ПРЕОБРАЗУЮЩИЙ ЧАСТИ ПРОГРАММЫ БУРЕНИЯ В ЕДИНЫЙ ФАЙЛ ПЕЧАТНОГО ФОРМАТА (pdf) + +1. На Linux сервер необходимо установить пакеты LibreOffice: + + sudo apt-get install libreoffice-writer libreoffice-calc + +2. путь до бинарника LibreOffice: +Linux - /usr/bin/soffice +Windows - C:\Program Files\LibreOffice\program\soffice.exe + +3. В массиве fileExtensions содержатся в виде стринг переменных необходимые расширения файлов +изначально обозначенные в задаче. +При необходимости список можно расширить. +На текущий момент, по логике метода класса, прикрепленные файлы +с "ненужным" или "неправильным" форматом просто не будут попадать в список на преобразование. + + + + diff --git a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs index 9ef92fd8..16ee2191 100644 --- a/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs +++ b/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramService.cs @@ -4,6 +4,7 @@ using AsbCloudApp.Repositories; using AsbCloudApp.Services; using AsbCloudDb.Model; using AsbCloudInfrastructure.Background; +using AsbCloudInfrastructure.Services.DrillingProgram.Convert; using Mapster; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; @@ -474,13 +475,13 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram var well = (await wellService.GetOrDefaultAsync(idWell, token))!; var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx"; var tempResultFilePath = Path.Combine(Path.GetTempPath(), "drillingProgram", resultFileName); - + var converter = new ConvertToPdf(); var workAction = async (string workId, IServiceProvider serviceProvider, CancellationToken token) => { var context = serviceProvider.GetRequiredService(); var fileService = serviceProvider.GetRequiredService(); - var files = state.Parts.Select(p => fileService.GetUrl(p.File)); - DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath, state.Parts, well); + var files = state.Parts.Select(p => fileService.GetUrl(p.File)); + await converter.GetConverteAndMergedFileAsync(files, tempResultFilePath); await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token); }; diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 754e0194..75360a36 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,39 +1,123 @@ -using AsbCloudApp.Data; -using AsbCloudApp.Data.DailyReport; -using AsbCloudDb; -using AsbCloudDb.Model; -using AsbCloudInfrastructure; -using AsbCloudInfrastructure.Services.DailyReport; -using AsbCloudInfrastructure.Services.SAUB; -using ClosedXML.Excel; -using DocumentFormat.OpenXml.Wordprocessing; -using Microsoft.EntityFrameworkCore; -using Org.BouncyCastle.Utilities.Collections; +using iTextSharp.text.pdf; using System; -using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; using System.Threading.Tasks; +using Document = iTextSharp.text.Document; +using CliWrap; namespace ConsoleApp1 { class Program { - private static AsbCloudDbContext db = ServiceFactory.Context; - - // use ServiceFactory to make services static void Main(/*string[] args*/) { - DependencyInjection.MapsterSetup(); - var sw = System.Diagnostics.Stopwatch.StartNew(); + string[] fileExtension = { ".xlsx", ".xls", ".ods", ".odt", ".doc", ".docx", ".pdf" }; + Console.WriteLine($"start convert"); + var inputFiles = new List(); + var resultFile = "C:\\Test\\result.pdf"; + inputFiles.Add("11112222.docx"); + inputFiles.Add("11117777.pdf"); + inputFiles.Add("22223333.xls"); + inputFiles.Add("33334444.xlsx"); - - - sw.Stop(); - Console.WriteLine($"total time: {sw.ElapsedMilliseconds} ms"); + var listOutNames = new List(); + var filteredFilesNames = inputFiles + .Distinct() + .Where(f => fileExtension.Any(fe => f.ToLower().EndsWith(fe))) + .ToList(); + foreach (var FileName in inputFiles) + { + var outputFile = Path.ChangeExtension(FileName, ".pdf"); + var outFile = StartConvertProcessAsync(FileName, outputFile); + Console.WriteLine($"convert file - {FileName}"); + Console.ReadLine(); + listOutNames.Add(outFile.Result.ToString()); + } + Console.WriteLine("merged files"); Console.ReadLine(); + DoMerged(listOutNames, resultFile); + } + + public static void DoMerged(IEnumerable inputFiles, string outFile) + { + using (FileStream stream = new FileStream(outFile, FileMode.Create)) + using (Document doc = new Document()) + using (PdfCopy pdf = new PdfCopy(doc, stream)) + { + doc.Open(); + PdfReader? reader = null; + PdfImportedPage? page = null; + inputFiles.ToList().ForEach(file => + { + reader = new PdfReader(file); + for (int i = 0; i < reader.NumberOfPages; i++) + { + page = pdf.GetImportedPage(reader, i + 1); + pdf.AddPage(page); + } + pdf.FreeReader(reader); + reader.Close(); + File.Delete(file); + }); + } + } + + //public static void StartConvertProcess(string inputFileName, string outFileName) + //{ + // using (Process pdfprocess = new Process()) + // { + // pdfprocess.StartInfo.UseShellExecute = true; + // //pdfprocess.StartInfo.LoadUserProfile = true; + // pdfprocess.StartInfo.FileName = "soffice"; + // pdfprocess.StartInfo.Arguments = $"--headless --convert-to pdf {inputFileName} --outdir {outFileName}"; + // pdfprocess.StartInfo.WorkingDirectory = "/usr/bin"; + // pdfprocess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; + // pdfprocess.Start(); + // if (!pdfprocess.WaitForExit(1000 * 60 * 1)) + // { + // pdfprocess.Kill(); + // } + // pdfprocess.Close(); + // } + //} + private static async Task StartConvertProcessAsync(string inputFileName, string outFileName) + { + //string outPath = "/home/eddie/Test/OutFiles"; + string outPath = "C:\\Test\\OutFiles"; + var result = Cli.Wrap("C:\\Program Files\\LibreOffice\\program\\soffice.exe") + .WithArguments($"-headless -convert-to pdf C:\\Test\\InFiles\\{inputFileName} -outdir {outPath}"); + await result.ExecuteAsync(); + var outFile = $"{outPath}\\{outFileName}"; + return outFile; + } + + public static async Task GetConverteAndMergedFileAsync(IEnumerable filesNames, string resultPath) + { + string[] fileExtension = { ".xlsx", ".xls", ".ods", ".odt", ".doc", ".docx", ".pdf" }; + //var filteredFilesNames = filesNames.Distinct(); + var filteredFilesNames = filesNames + .Distinct() + .Where(f => fileExtension.Any(fe => f.ToLower().EndsWith(fe))) + .ToList(); + var listFileNames = filteredFilesNames + .ToList() + .Select(o => new { + inputFile = o, + convertedFile = Path.ChangeExtension(o, ".pdf") + }); + foreach (var excelFileName in listFileNames) + { + await StartConvertProcessAsync(excelFileName.inputFile, excelFileName.convertedFile); + Console.WriteLine($"convert file - {excelFileName.inputFile}"); + Console.ReadLine(); + } + + Console.WriteLine("merged files"); + Console.ReadLine(); + DoMerged(listFileNames.Select(c => c.convertedFile), resultPath); + } } } diff --git a/ConsoleApp1/ReadMe.md b/ConsoleApp1/ReadMe.md new file mode 100644 index 00000000..1ddf6367 --- /dev/null +++ b/ConsoleApp1/ReadMe.md @@ -0,0 +1,25 @@ +ТЕСТ РАБОТЫ КЛАССА КОНВЕРТИРУЮЩЕГО ЧАСТИ ПРОГРАММЫ БУРЕНИЯ В ЕДИНЫЙ ФАЙЛ ПЕЧАТНОГО ФОРМАТА (pdf) + +Тест настроен под проверку на винде +для проверки необходимо создать иерархию папок (в корне С:\) +C:\Test\InFiles и C:\Test\OutFiles + +Для простоты тестирования имена файлов подлежащих конвертации + "зашиты" в код + + + +Для теста/работы на линукс машинах + +на Linux сервер необходимо установить пакеты LibreOffice + +sudo apt-get install libreoffice-writer libreoffice-calc + + перед компиляцией необходимо изменить пути к файлам и папкам + +например : +C:\Test\InFiles => /home/{папка юзера}/Test/InFiles + +путь до бинарника LibreOffice: +Linux - /usr/bin/soffice +Windows - C:\Program Files\LibreOffice\program\soffice.exe \ No newline at end of file