【问题标题】:Split a large Excel file into multiple, based on row count根据行数将大型 Excel 文件拆分为多个
【发布时间】:2023-03-17 08:47:02
【问题描述】:

我有一个 C# 控制台应用程序,它需要根据行数将大型 Excel 拆分为多个 Excel 文件。下面的代码显示了一个只有 51 行(包括标题列行)的源文件,但最终的源文件将有 100,000+ 行。

代码试图跳过第一行(标题),然后应该从第 2 行复制到第 11 行,依此类推——我将目标文件设置为每个文件只有 10 行,以加快开发速度。

问题 那么如何从源 Excel 文件中复制第 2 行到第 11 行以及随后的 10 行并粘贴到多个目标 Excel 文件中,以便每个目标文件都能有10行?

这是几乎新编写的代码。它松散地基于copying of specific range of excel cells from one worksheet to another worksheethttps://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 行开始),而第 2 个文件只有 3 行,从第 10 行开始,第 3 个文件有 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;

            }

【问题讨论】:

  • 有什么问题?
  • 我不知道如何从第 2 行复制到第 11 行,依此类推,然后粘贴到新的目标文件中。
  • 更新了问题以尝试清楚地询问需要什么。谢谢。
  • 我将目标文件设置为每个文件仅 10 行,以加快开发速度 拆分大文件后您要做什么成多个。而且我不认为,读取大文件并将其分成5个不同的文件会使开发更快。
  • 我的源 excel 文件太大而无法输入另一个进程,因此我需要将其拆分为一些块。目前,手动进行,但这不是长期解决方案。谢谢。

标签: c# excel split


【解决方案1】:

我建议使用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());
}

【讨论】:

  • 谢谢。我想我已经足够接近了,这个应用程序将只适合我在我已经安装了 Excel 的桌面上使用。所以如果我能弄清楚行的复制/粘贴,从行号开始到结束行号,那么我应该很好。
  • 请看代码的转贴;我想我更接近了。谢谢。
【解决方案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
}

【讨论】:

  • 非常感谢您分享此代码。帮了我很多:)
猜你喜欢
  • 2022-01-12
  • 2019-06-14
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
相关资源
最近更新 更多