Разделете голям Excel файл на няколко въз основа на броя на редовете

Имам C# конзолно приложение, което се нуждае от голям Excel, за да бъде разделен на множество Excel файлове въз основа на броя на редовете. Кодът по-долу показва изходен файл само с 51 реда (включително редовете на заглавната колона), но крайният изходен файл ще има 100 000+ реда.

Кодът се опитва да пропусне първия (заглавен) ред и след това трябва да копира от редове 2 до 11 и така нататък - целевите файлове са зададени само на 10 реда на файл, за да направя разработката по-бърза.

Въпрос И така, как да копирам редове от 2 до 11 и следващите 10 реда от изходния файл на Excel и да ги поставя в множество целеви файлове на Excel, така че всеки целеви файл да има по 10 реда ?

Ето го почти новонаписания код. Той се базира на копиране на конкретен диапазон от клетки на Excel от един работен лист в друг работен лист и https://social.msdn.microsoft.com/Forums/vstudio/en-US/afd01976-63d0-4f96-9ba4-e3e2b6cf8d55/excel-with-c-how-to-specify-a-range-?forum=vsto

Сега мога да напиша 5 Excel файла. Но първият файл има 9 реда (започвайки от ред 2), докато вторият файл има само 3 реда, започвайки с ред 10, третият има 13 реда, започвайки отново с ред 10; последните два файла имат постепенно повече редове, като и двата започват с ред 10.

Значи нещо не е наред с моя For Loop? Или начинът, по който избирам ranges?

     string startPath = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
            string filePath_source = Path.Combine(startPath, @"Source_Files\Offers_Source_Temp.xlsx");
            string filePath_copiedinto = Path.Combine(startPath, @"Source_Files\ToBeCopiedInto.xlsx");
           app = new Excel.Application();
           app.DisplayAlerts = false;
           book = app.Workbooks.Open(filePath_source);
            sheet = (Excel.Worksheet)book.Worksheets.get_Item((1));              
            int iRowCount = sheet.UsedRange.Rows.Count;
            int maxrows = 10;//change this to something like 50,000 later.  01/16/18
            int maxloops = iRowCount / maxrows;
            int beginrow = 2; //skipping the header row.
            Excel.Application destxlApp;
            Excel.Workbook destworkBook;
            Excel.Worksheet destworkSheet;
            Excel.Range destrange;
            string srcPath;
            string destPath;
            //Opening of first worksheet and copying
            srcPath = filePath_source;
            for (int i = 1; i <= maxloops; i++)   {
                Excel.Range rng = (Excel.Range)sheet.Range[sheet.Cells[beginrow, 1], sheet.Cells[maxrows, 3]];
                rng.Copy(Type.Missing);
                //opening of the second worksheet and pasting
                destPath = filePath_copiedinto; 
                destxlApp = new Excel.Application();
                destxlApp.DisplayAlerts = false;
                destworkBook = destxlApp.Workbooks.Open(destPath, 0, false);
                destworkSheet = destworkBook.Worksheets.get_Item(1);
                destrange = destworkSheet.Cells[1, 1];
                destrange.Select();
                destworkSheet.Paste(Type.Missing, Type.Missing);                   
                destworkBook.SaveAs(startPath + "\\Output_Files\\" + beginrow + ".xlsx");                    
                destworkBook.Close(true, null, null);
                destxlApp.Quit();
                beginrow = beginrow + maxrows;
                string blah = null;

            }

person IrfanClemson    schedule 17.01.2018    source източник
comment
Какъв е проблема?   -  person Syntax Error    schedule 17.01.2018
comment
Не знам как да копирам от редове 2 до 11 и така нататък и след това да поставя в нови целеви файлове.   -  person IrfanClemson    schedule 17.01.2018
comment
Актуализирах въпроса, за да се опитам да попитам ясно какво е необходимо. Благодаря.   -  person IrfanClemson    schedule 17.01.2018
comment
Имам целевите файлове, зададени само на 10 реда на файл, за да направя разработката по-бърза Какво се опитвате да направите с След като разделите големия файл на няколко. И не мисля, че четенето на големия файл и превръщането му в 5 различни файла ще направи разработката по-бърза.   -  person Kavin    schedule 17.01.2018
comment
Моят изходен excel файл е твърде голям, за да бъде въведен в друг процес и затова трябва да го разделя на няколко части. В момента го правя ръчно, но това не е дългосрочно решение. Благодаря.   -  person IrfanClemson    schedule 17.01.2018
comment
Така че искате конзолното приложение да се използва само за разделяне на големия файл на множество. Ако е така, тогава има смисъл. Благодаря   -  person Kavin    schedule 17.01.2018


Отговори (2)


Схванах го! В моя преработен код във въпроса се доближих, но имах някакъв проблем в For Loop; поправи го според кода по-долу. Ето го почти пълния код. Благодаря на всички за помощта!!

  try
        {               
            string startPath = System.IO.Path.GetDirectoryName(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
            string filePath_source = Path.Combine(startPath, @"Source_Files\Offers_Source_Temp.xlsx");
            string filePath_copiedinto = Path.Combine(startPath, @"Source_Files\ToBeCopiedInto.xlsx");
           app = new Excel.Application();
           app.DisplayAlerts = false;
           book = app.Workbooks.Open(filePath_source);
            sheet = (Excel.Worksheet)book.Worksheets.get_Item((1));              
            int iRowCount = sheet.UsedRange.Rows.Count;              
            int countColumns = sheet.UsedRange.Columns.Count;
            int maxrows = 10;//change this to something like 50,000 later.  01/16/18
            int maxloops = iRowCount / maxrows;
            int beginrow = 2; //skipping the header row.
            Excel.Application destxlApp;
            Excel.Workbook destworkBook;
            Excel.Worksheet destworkSheet;
            Excel.Range destrange;
            string srcPath;
            string destPath;
            //Opening of first worksheet and copying
            srcPath = filePath_source;
            for (int i = 1; i <= maxloops; i++)   {
                ///  Excel.Range rng = (Excel.Range)sheet.Range[sheet.Cells[beginrow, 1], sheet.Cells[maxrows, 3]];
                Excel.Range startCell = sheet.Cells[beginrow, 1];//not sure the second parameter needed?
                Excel.Range endCell = sheet.Cells[beginrow+maxrows-1, 3];//not sure the second parameter needed?
                Excel.Range rng = sheet.Range[startCell, endCell];
                rng = rng.EntireRow;//so second parameters above should not be needed. But doesn't work without it!
                rng.Copy(Type.Missing);
                //opening of the second worksheet and pasting
                destPath = filePath_copiedinto; 
                destxlApp = new Excel.Application();
                destxlApp.DisplayAlerts = false;
                destworkBook = destxlApp.Workbooks.Open(destPath, 0, false);
                destworkSheet = destworkBook.Worksheets.get_Item(1);
                destrange = destworkSheet.Cells[1, 1];
                destrange.Select();
                destworkSheet.Paste(Type.Missing, Type.Missing);                   
                destworkBook.SaveAs(startPath + "\\Output_Files\\" + beginrow + ".xlsx");                    
                destworkBook.Close(true, null, null);
                destxlApp.Quit();
                beginrow = beginrow + maxrows;


            }//for loop
}
person IrfanClemson    schedule 17.01.2018
comment
Благодаря ви много, че споделихте този код. Помогна ми много :) - person Karthic Srinivasan; 05.12.2019

Бих предложил да използвате библиотеката OpenXml за изпълнение на тази задача. Той е без зависимости и поддържа цялата OpenXml структура. Ето начална точка как да четете/пишете редовете:

using System;
using System.Linq;
using DocumentFormat.OpenXml;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;

// Open the document for editing.
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(fileName, false))
{
    WorkbookPart workbookPart = spreadsheetDocument.WorkbookPart;
    WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
    SheetData sheetData = worksheetPart.Worksheet.Elements<SheetData>().First();

    foreach (Row r in sheetData.Elements<Row>())
    {

    }
}

Сега писането е много подобно:

using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Create(fileName),
    SpreadsheetDocumentType.Workbook))
{
    // create the workbook
    spreadSheet.AddWorkbookPart();
    spreadSheet.WorkbookPart.Workbook = new Workbook ();     // create the worksheet
    spreadSheet.WorkbookPart.AddNewPart<WorksheetPart>();
    spreadSheet.WorkbookPart.WorksheetParts.First().Worksheet = new Worksheet();

    // create sheet data
    spreadSheet.WorkbookPart.WorksheetParts.First().Worksheet.AppendChild(new SheetData());
    // create row
    spreadSheet.WorkbookPart.WorksheetParts.First().Worksheet.First().AppendChild(new Row());
}
person CodeTherapist    schedule 17.01.2018
comment
Благодаря ти. Мисля, че съм достатъчно близо и това приложение ще бъде само за мен на моя работен плот, където Excel вече е инсталиран. Така че, ако мога да разбера копирането/поставянето на редове, като се започне от номерата на редовете до крайните номера на редовете, тогава трябва да съм добър. - person IrfanClemson; 17.01.2018
comment
Моля, вижте повторно публикуване на кода; Мисля, че съм по-близо. Благодаря. - person IrfanClemson; 17.01.2018