add ConvertToPdf class

add ReadMe
add test to ConsoleApp1
This commit is contained in:
eugeniy_ivanov 2023-01-13 17:28:04 +05:00
parent cfab294945
commit c2afbf4d55
6 changed files with 222 additions and 25 deletions

View File

@ -35,9 +35,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.0" />
<PackageReference Include="ClosedXML" Version="0.96.0" /> <PackageReference Include="ClosedXML" Version="0.96.0" />
<PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" /> <PackageReference Include="FluentValidation.AspNetCore" Version="11.2.2" />
<PackageReference Include="itext7" Version="7.2.3" /> <PackageReference Include="itext7" Version="7.2.3" />
<PackageReference Include="iTextSharp" Version="5.5.13.3" />
<PackageReference Include="Mapster" Version="7.3.0" /> <PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" /> <PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.1" />
<PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.23.1" /> <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="6.23.1" />

View File

@ -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<string> 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<string> 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);
}
}
}

View File

@ -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 содержатся в виде стринг переменных необходимые расширения файлов
изначально обозначенные в задаче.
При необходимости список можно расширить.
На текущий момент, по логике метода класса, прикрепленные файлы
с "ненужным" или "неправильным" форматом просто не будут попадать в список на преобразование.

View File

@ -4,6 +4,7 @@ using AsbCloudApp.Repositories;
using AsbCloudApp.Services; using AsbCloudApp.Services;
using AsbCloudDb.Model; using AsbCloudDb.Model;
using AsbCloudInfrastructure.Background; using AsbCloudInfrastructure.Background;
using AsbCloudInfrastructure.Services.DrillingProgram.Convert;
using Mapster; using Mapster;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -474,13 +475,13 @@ namespace AsbCloudInfrastructure.Services.DrillingProgram
var well = (await wellService.GetOrDefaultAsync(idWell, token))!; var well = (await wellService.GetOrDefaultAsync(idWell, token))!;
var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx"; var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx";
var tempResultFilePath = Path.Combine(Path.GetTempPath(), "drillingProgram", resultFileName); var tempResultFilePath = Path.Combine(Path.GetTempPath(), "drillingProgram", resultFileName);
var converter = new ConvertToPdf();
var workAction = async (string workId, IServiceProvider serviceProvider, CancellationToken token) => var workAction = async (string workId, IServiceProvider serviceProvider, CancellationToken token) =>
{ {
var context = serviceProvider.GetRequiredService<IAsbCloudDbContext>(); var context = serviceProvider.GetRequiredService<IAsbCloudDbContext>();
var fileService = serviceProvider.GetRequiredService<FileService>(); var fileService = serviceProvider.GetRequiredService<FileService>();
var files = state.Parts.Select(p => fileService.GetUrl(p.File)); var files = state.Parts.Select(p => fileService.GetUrl(p.File));
DrillingProgramMaker.UniteExcelFiles(files, tempResultFilePath, state.Parts, well); await converter.GetConverteAndMergedFileAsync(files, tempResultFilePath);
await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token); await fileService.MoveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, tempResultFilePath, token);
}; };

View File

@ -1,39 +1,123 @@
using AsbCloudApp.Data; using iTextSharp.text.pdf;
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 System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Document = iTextSharp.text.Document;
using CliWrap;
namespace ConsoleApp1 namespace ConsoleApp1
{ {
class Program class Program
{ {
private static AsbCloudDbContext db = ServiceFactory.Context;
// use ServiceFactory to make services
static void Main(/*string[] args*/) static void Main(/*string[] args*/)
{ {
DependencyInjection.MapsterSetup(); string[] fileExtension = { ".xlsx", ".xls", ".ods", ".odt", ".doc", ".docx", ".pdf" };
var sw = System.Diagnostics.Stopwatch.StartNew(); Console.WriteLine($"start convert");
var inputFiles = new List<string>();
var resultFile = "C:\\Test\\result.pdf";
inputFiles.Add("11112222.docx");
inputFiles.Add("11117777.pdf");
inputFiles.Add("22223333.xls");
inputFiles.Add("33334444.xlsx");
var listOutNames = new List<string>();
var filteredFilesNames = inputFiles
sw.Stop(); .Distinct()
Console.WriteLine($"total time: {sw.ElapsedMilliseconds} ms"); .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(); Console.ReadLine();
DoMerged(listOutNames, resultFile);
}
public static void DoMerged(IEnumerable<string> 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<string> 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<string> 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);
} }
} }
} }

25
ConsoleApp1/ReadMe.md Normal file
View File

@ -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