DD.WellWorkover.Cloud/ConsoleApp1/Program.cs
2021-09-23 15:26:54 +05:00

171 lines
7.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//using AsbSaubReport;
//using AutoMapper;
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using ClosedXML.Excel;
using ClosedXML.Excel.Drawings;
namespace ConsoleApp1
{
//var options = new DbContextOptionsBuilder<AsbCloudDbContext>()
// .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True")
// .Options;
//var context = new AsbCloudDbContext(options);
class Program
{
private static IXLWorksheet CopyImagesToAnotherSheet(IXLWorksheet sourceSheet, IXLWorksheet resultSheet)
{
foreach (var picture in sourceSheet.Pictures)
{
resultSheet.AddPicture(picture.ImageStream)
.WithPlacement(XLPicturePlacement.Move)
.WithSize(picture.Width, picture.Height)
.MoveTo(resultSheet.Cell(picture.TopLeftCell.Address),
picture.Left, picture.Top);
}
return resultSheet;
}
private static void RemovePicturesFromSheet(IXLWorksheet sheet)
{
var picsNames = new List<string>();
foreach (var p in sheet.Pictures)
picsNames.Add(p.Name);
var filteredPics = picsNames.Distinct();
foreach (var n in filteredPics)
sheet.Pictures.Delete(n);
}
private static IXLRange GetCellsRange(IXLWorksheet sheet)
{
var firstTableCell = sheet.FirstCellUsed();
var lastTableCell = sheet.LastCellUsed();
var rngData = sheet.Range(firstTableCell.Address, lastTableCell.Address);
return rngData;
}
// Изображения не переносятся при вызове метода sheet.CopyTo(). Падает с exception.
// Для этого сначала все изображения переносятся на временный лист "PicsCopy",
// затем удаляются из копируемого листа, копируемый лист копируется в лист-результат
// и после этого из temp листа "PicsCopy" в лист-результат также копируются изображения.
private static void CopySheetToFile(IXLWorksheet currentSheet, XLWorkbook resultExcelFile)
{
var picturesCopySheet = resultExcelFile.AddWorksheet("PicsCopy");
CopyImagesToAnotherSheet(currentSheet, picturesCopySheet);
RemovePicturesFromSheet(currentSheet);
var resultSheet = currentSheet.CopyTo(resultExcelFile, currentSheet.Name);
CopyImagesToAnotherSheet(picturesCopySheet, resultSheet);
picturesCopySheet.Delete();
}
static void Main(/*string[] args*/)
{
var sourceExcelPaths = new List<string>
{
//@"D:\excels\excel1.xlsx",
//@"D:\excels\excel2.xlsx"
@"D:\excels\e1.xlsx",
@"D:\excels\e2.xlsx",
@"D:\excels\e3.xlsx",
@"D:\excels\e4.XLSX",
@"D:\excels\e5.XLSX",
@"D:\excels\e6.XLSX"
};
const string resultExcelPath = @"D:\excels\result.xlsx";
using var resultExcelFile = new XLWorkbook();
const int maxAllowedColumns = 256;
foreach(var sourceExcelPath in sourceExcelPaths)
{
using var sourceExcelFile = new XLWorkbook(sourceExcelPath);
Console.WriteLine($"Добавляется файл {Path.GetFileName(sourceExcelPath)}");
foreach (var sheet in sourceExcelFile.Worksheets)
{
// Если в файле очень много колонок и многие из них пустые -
// предлагаем удалить их вручную или пытаемся копировать
// ячейки попорядку (не красиво). Красиво не получится.
if (sheet.Columns().Count() > maxAllowedColumns &&
sheet.Columns().Count() / sheet.ColumnsUsed().Count() > 3)
{
Console.WriteLine($"В файле {Path.GetFileName(sourceExcelPath)} " +
$"{sheet.Columns().Count() - sheet.ColumnsUsed().Count()} пустых колонок " +
$"без записей.\nЕсли продолжить выполнение, форматирование выходного " +
$"листа может быть нарушено.\nДля сохранения структуры документа " +
$"рекомендуется прервать выполнение и удалить неиспользуемые колонки.\n" +
$"Продолжить выполнение? (y/n)");
var res = Console.ReadLine();
if (res != "y")
return;
var resultSheet = resultExcelFile.Worksheets.Add(sheet.Name);
var rngData = GetCellsRange(sheet);
rngData.CopyTo(resultSheet.Cell(1, 1));
var lastRowWithData = rngData.LastRowUsed().RangeAddress.LastAddress.RowNumber;
for (int i = 1; i < lastRowWithData; i++)
{
resultSheet.Row(i).Height = sheet.Row(i).Height;
resultSheet.Column(i).Width = sheet.Column(i).Width;
}
CopyImagesToAnotherSheet(sheet, resultSheet);
GC.Collect();
}
// Если колонок в файле немного, но среди них также есть пустые -
// проще удалить ненужные колонки и скопировать лист красиво.
else if (sheet.Columns().Count() < maxAllowedColumns &&
sheet.Columns().Count() / sheet.ColumnsUsed().Count() > 2)
{
var columnsToDelete = sheet.Columns()
.Skip(sheet.ColumnsUsed().Count());
foreach (var d in columnsToDelete)
d.Delete();
CopySheetToFile(sheet, resultExcelFile);
GC.Collect();
}
// Если по колонкам все хорошо, копируем лист красиво.
else
{
CopySheetToFile(sheet, resultExcelFile);
GC.Collect();
}
}
}
resultExcelFile.SaveAs(resultExcelPath);
Console.WriteLine("Done. Press any key to quit.");
Console.ReadKey();
}
}
}