Advertisement
Guest User

Untitled

a guest
Jun 13th, 2016
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.39 KB | None | 0 0
  1. using System.Collections.Generic;
  2. using System.Globalization;
  3. using System.Linq;
  4. using DocumentFormat.OpenXml.Packaging;
  5. using DocumentFormat.OpenXml.Spreadsheet;
  6.  
  7. namespace ExcelThingy
  8. {
  9.     internal class Item
  10.     {
  11.         public string Code { get; set; }
  12.         public double? Price { get; set; }
  13.     }
  14.  
  15.     class Program
  16.     {
  17.         // путь к файлу
  18.         const string FilePath = "testing2.xlsx";
  19.  
  20.         // колонка с кодами вещей, которые мы будем сравнивать
  21.         const string FirstCodeColumn = "A";
  22.         // колонка с ценами вещей, которые мы будем сравнивать
  23.         const string FirstPriceColumn = "B";
  24.         // колонка с кодами вещей, с которыми мы будем сравнивать
  25.         const string SecondCodeColumn = "D";
  26.         // колонка с ценами вещей, с которыми мы будем сравнивать
  27.         const string SecondPriceColumn = "E";
  28.  
  29.         static void Main(string[] args)
  30.         {
  31.  
  32.             // создаем пару словарей, в первом будут храниться коды и цены из первых колонок
  33.             // во втором- цены и коды из второй пары колонок
  34.             var originalItems = new List<Item>();
  35.             var otherItems = new List<Item>();
  36.  
  37.             // открываем xlsx файлик на чтение
  38.             using (var spreadsheetDocument =
  39.                 SpreadsheetDocument.Open(FilePath, true))
  40.             {
  41.                 var workbookPart = spreadsheetDocument.WorkbookPart;
  42.                 var worksheetPart = workbookPart.WorksheetParts.First();
  43.                 var sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();
  44.                 var stringTablePart = workbookPart.GetPartsOfType<SharedStringTablePart>().First();
  45.                 var stringTable = stringTablePart.SharedStringTable;
  46.  
  47.                 foreach (var row in sheetData.Elements<Row>())
  48.                 {
  49.                     // пропускаем первую строку, если надо
  50.                     if (row.RowIndex == 1) continue;
  51.  
  52.                     // собираем все интересующие нас ячейки
  53.                     var cells = row.Elements<Cell>().ToList();
  54.                     var firstPriceCell = cells.FirstOrDefault(c => c.CellReference.Value.Equals(FirstPriceColumn + row.RowIndex));
  55.                     var firstCodeCell = cells.FirstOrDefault(c => c.CellReference.Value.Equals(FirstCodeColumn + row.RowIndex));
  56.                     var secondPriceCell = cells.FirstOrDefault(c => c.CellReference.Value.Equals(SecondPriceColumn + row.RowIndex));
  57.                     var secondCodeCell = cells.FirstOrDefault(c => c.CellReference.Value.Equals(SecondCodeColumn + row.RowIndex));
  58.  
  59.                     // вытягиваем информацию из этих ячеек и наполняем наши словари
  60.                     var firstPrice = ReadCellValue(firstPriceCell, stringTable);
  61.                     var firstCode = ReadCellValue(firstCodeCell, stringTable);
  62.                     var secondPrice = ReadCellValue(secondPriceCell, stringTable);
  63.                     var secondCode = ReadCellValue(secondCodeCell, stringTable);
  64.  
  65.                     if (!string.IsNullOrWhiteSpace(firstCode))
  66.                         originalItems.Add(new Item
  67.                         {
  68.                             Code = firstCode,
  69.                             Price = double.Parse(firstPrice, NumberStyles.Float)
  70.                         });
  71.  
  72.                     if (!string.IsNullOrWhiteSpace(secondCode))
  73.                         otherItems.Add(new Item
  74.                         {
  75.                             Code = secondCode,
  76.                             Price = double.Parse(secondPrice, NumberStyles.Float)
  77.                         });
  78.                 }
  79.  
  80.                 // находим все позиции из первой пары колонок с меньшей ценой
  81.                 var cheaperItems = new List<Item>();
  82.  
  83.                 // группируем первую пару столбцов по ключу
  84.                 var groups = originalItems.GroupBy(i => i.Code);
  85.                
  86.                 foreach (var g in groups)
  87.                 {
  88.                     // находим элемент, с которым необходимо сравнить элементы из группы
  89.                     var compareTo = otherItems.FirstOrDefault(i => i.Code == g.Key);
  90.                     if(compareTo == null)
  91.                         continue;
  92.  
  93.                     // сравниваем и добавляем те, что дешевле, в коллекцию-результат
  94.                     cheaperItems.AddRange(g.Where(i => i.Price < compareTo.Price));
  95.                 }
  96.  
  97.                
  98.                 // создаем новый лист в документе
  99.                 var newWorksheetPart = spreadsheetDocument.WorkbookPart.AddNewPart<WorksheetPart>();
  100.                 newWorksheetPart.Worksheet = new Worksheet(new SheetData());
  101.  
  102.                 var sheets = spreadsheetDocument.WorkbookPart.Workbook.GetFirstChild<Sheets>();
  103.                 var relationshipId =
  104.                     spreadsheetDocument.WorkbookPart.GetIdOfPart(newWorksheetPart);
  105.  
  106.                 var sheetId = 1u;
  107.                 if (sheets.Elements<Sheet>().Any())
  108.                 {
  109.                     sheetId =
  110.                         sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1;
  111.                 }
  112.  
  113.                 var sheetName = "CheaperItems" + sheetId;
  114.  
  115.                 var sheet = new Sheet
  116.                 {
  117.                     Id = relationshipId, SheetId = sheetId, Name = sheetName
  118.                 };
  119.                 sheets.Append(sheet);
  120.                 workbookPart.Workbook.Save();
  121.  
  122.                 // проходимся по словарю вещей на запись и пишем по две ячейки в каждую строку
  123.                 var rowIndex = 1u;
  124.                 foreach(var item in cheaperItems)
  125.                 {
  126.                     var codeCell = InsertCellInWorksheet(FirstCodeColumn, rowIndex, newWorksheetPart);
  127.                     codeCell.CellValue = new CellValue(item.Code);
  128.                     codeCell.DataType = CellValues.String;
  129.                     var priceCell = InsertCellInWorksheet(FirstPriceColumn, rowIndex, newWorksheetPart);
  130.                     priceCell.CellValue = new CellValue(item.Price + "");
  131.                     priceCell.DataType = CellValues.Number;
  132.                     rowIndex++;
  133.                 }
  134.                 workbookPart.Workbook.Save();
  135.  
  136.  
  137.             } // после этой скобки поток закроется и файл станет доступным для других процессов
  138.         }
  139.  
  140.         private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart)
  141.         {
  142.             Worksheet worksheet = worksheetPart.Worksheet;
  143.             SheetData sheetData = worksheet.GetFirstChild<SheetData>();
  144.             string cellReference = columnName + rowIndex;
  145.  
  146.             // If the worksheet does not contain a row with the specified row index, insert one.
  147.             Row row;
  148.             if (sheetData.Elements<Row>().Count(r => r.RowIndex == rowIndex) != 0)
  149.             {
  150.                 row = sheetData.Elements<Row>().First(r => r.RowIndex == rowIndex);
  151.             }
  152.             else
  153.             {
  154.                 row = new Row() { RowIndex = rowIndex };
  155.                 sheetData.Append(row);
  156.             }
  157.  
  158.             // If there is not a cell with the specified column name, insert one.  
  159.             if (row.Elements<Cell>().Any(c => c.CellReference.Value == columnName + rowIndex))
  160.             {
  161.                 return row.Elements<Cell>().First(c => c.CellReference.Value == cellReference);
  162.             }
  163.             // Cells must be in sequential order according to CellReference. Determine where to insert the new cell.
  164.             var refCell = row.Elements<Cell>().FirstOrDefault(cell => string.Compare(cell.CellReference.Value, cellReference, true) > 0);
  165.  
  166.             var newCell = new Cell() { CellReference = cellReference };
  167.             row.InsertBefore(newCell, refCell);
  168.  
  169.             worksheet.Save();
  170.             return newCell;
  171.         }
  172.  
  173.         private static string ReadCellValue(Cell cell, SharedStringTable stringTable)
  174.         {
  175.             if (cell == null || cell.CellValue == null)
  176.                 return null;
  177.             if ((cell.DataType != null) && (cell.DataType == CellValues.SharedString))
  178.             {
  179.                 var ssid = int.Parse(cell.CellValue.Text);
  180.                 return stringTable.ChildElements[ssid].InnerText;
  181.             }
  182.  
  183.             if ((cell.DataType != null) && (cell.DataType == CellValues.Number))
  184.             {
  185.                 // формат дробных чисел между экселем и .NET может не совпадать, поэтому возможно будет необходимо заменить дробную запятую на дробную точку
  186.                 return cell.CellValue.Text.Replace(',', '.');
  187.             }
  188.  
  189.             return cell.CellValue.Text;
  190.         }
  191.     }
  192. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement