C#代碼實(shí)現(xiàn)重新排列Excel中的列
適當(dāng)調(diào)整 Excel 中列的順序可以提高數(shù)據(jù)的可讀性。例如,將日期數(shù)據(jù)設(shè)置為第一列后,我們可以更快速地根據(jù)特定日期定位數(shù)據(jù)。在 Microsoft Excel 中,可以通過按住 Shift 鍵并拖動(dòng)列的方式輕松移動(dòng)列。本文將介紹如何在 C# 和 VB.NET 中以編程方式重新排列 Excel 中的列。
安裝所需組件
開始之前,需要在 .NET 項(xiàng)目中添加相關(guān)的 Excel 處理庫引用。可以通過下載 DLL 文件手動(dòng)添加,也可以直接通過 NuGet 安裝。
PM> Install-Package Spire.XLS
在 C# 和 VB.NET 中重新排列 Excel 列
以下是在 .NET 程序中重新排列 Excel 列的主要步驟:
- 創(chuàng)建
Workbook對象,并使用Workbook.LoadFromFile()方法加載 Excel 文件。 - 通過
Workbook.Worksheets[index]獲取目標(biāo)工作表。 - 使用
int數(shù)組指定新的列順序。 - 創(chuàng)建一個(gè)臨時(shí)工作表,并將目標(biāo)工作表中的數(shù)據(jù)復(fù)制到該工作表。
- 按照新的列順序,將臨時(shí)工作表中的列復(fù)制回目標(biāo)工作表。
- 刪除臨時(shí)工作表。
- 使用
Workbook.SaveToFile()方法保存修改后的 Excel 文件。
完整示例代碼如下:
using System.Linq;
using Spire.Xls;
namespace 調(diào)整Excel列順序
{
class Program
{
static void Main(string[] args)
{
// 創(chuàng)建 Workbook 對象
Workbook workbook = new Workbook();
// 加載 Excel 文件
workbook.LoadFromFile(@"C:\Users\Administrator\Desktop\sample.xlsx");
// 獲取第一個(gè)工作表
Worksheet worksheet = workbook.Worksheets[0];
// 設(shè)置新的列順序(列索引從 0 開始)
int[] newColumnOrder = new int[] { 3, 0, 1, 2, 4, 5 };
// 添加一個(gè)臨時(shí)工作表
Worksheet newSheet = workbook.Worksheets.Add("temp");
// 將第一個(gè)工作表中的數(shù)據(jù)復(fù)制到臨時(shí)工作表
newSheet.CopyFrom(worksheet);
// 遍歷 newColumnOrder 數(shù)組
for (int i = 0; i < newColumnOrder.Count(); i++)
{
// 將臨時(shí)工作表中的列復(fù)制到第一個(gè)工作表
newSheet.Columns[newColumnOrder[i]].Copy(worksheet.Columns[i], true, true);
// 設(shè)置目標(biāo)工作表列寬與臨時(shí)工作表對應(yīng)列寬一致
worksheet.Columns[i].ColumnWidth = newSheet.Columns[newColumnOrder[i]].ColumnWidth;
}
// 刪除臨時(shí)工作表
workbook.Worksheets.Remove(newSheet);
// 保存工作簿到新的 Excel 文件
workbook.SaveToFile("MoveColumn.xlsx", FileFormat.Version2016);
}
}
}知識擴(kuò)展
在 C# 或 VB.NET 中重新排列 Excel 工作表中的列,本質(zhì)上是將某一列(或某幾列)的數(shù)據(jù)整體移動(dòng)到新的位置。由于 Excel 沒有直接提供“移動(dòng)列”的 API,我們需要通過 插入空白列 → 復(fù)制數(shù)據(jù) → 刪除原列 或 直接交換列范圍 的方式來實(shí)現(xiàn)。
下面分別使用 Spire.XLS(免費(fèi)版可用但有限制)和 EPPlus(開源免費(fèi)) 演示如何實(shí)現(xiàn)。兩種方法均適用于 .NET Framework 和 .NET Core。
方法一:使用 Spire.XLS(適用于 .NET,商業(yè)庫但有免費(fèi)版)
Spire.XLS 提供了 Columns 集合和 Copy 方法,可以輕松實(shí)現(xiàn)列的移動(dòng)。
核心思路:
- 將目標(biāo)列的
Column.Copy()到目標(biāo)位置之前插入的新列。 - 刪除原始列。
// C# 示例
using Spire.Xls;
class Program
{
static void Main()
{
// 加載工作簿
Workbook workbook = new Workbook();
workbook.LoadFromFile("input.xlsx");
Worksheet sheet = workbook.Worksheets[0];
// 將第 3 列移動(dòng)到第 1 列前面(即新的第 1 列)
MoveColumn(sheet, 3, 1);
workbook.SaveToFile("output.xlsx", ExcelVersion.Version2016);
}
static void MoveColumn(Worksheet sheet, int sourceColIndex, int targetColIndex)
{
// 如果源列和目標(biāo)列相同,直接返回
if (sourceColIndex == targetColIndex) return;
// 獲取源列區(qū)域
CellRange sourceRange = sheet.Range[1, sourceColIndex, sheet.LastRow, sourceColIndex];
// 在目標(biāo)位置之前插入一列(如果 targetColIndex=1,則在第一列前插入)
sheet.InsertColumn(targetColIndex);
// 獲取新插入的列區(qū)域(現(xiàn)在位于 targetColIndex)
CellRange targetRange = sheet.Range[1, targetColIndex, sheet.LastRow, targetColIndex];
// 將源列數(shù)據(jù)復(fù)制到新插入的列
sourceRange.Copy(targetRange);
// 刪除原始列(注意:插入列后,原始列的索引會增加 1)
int newSourceColIndex = sourceColIndex + (sourceColIndex >= targetColIndex ? 1 : 0);
sheet.DeleteColumn(newSourceColIndex);
}
}優(yōu)點(diǎn):代碼簡潔,無需處理大量循環(huán)。
缺點(diǎn):Spire.XLS 免費(fèi)版有導(dǎo)出頁數(shù)和行數(shù)限制,適合小文件或評估。
方法二:使用 EPPlus(開源免費(fèi),僅支持 .xlsx)
EPPlus 不直接提供 InsertColumn/DeleteColumn,但可以通過操作 ExcelRange 的 Value 屬性來交換或移動(dòng)列數(shù)據(jù)。
核心思路:
- 將源列的數(shù)據(jù)讀取到一個(gè)二維數(shù)組。
- 在目標(biāo)位置插入一個(gè)空白列(通過向右偏移所有列來實(shí)現(xiàn))。
- 將數(shù)據(jù)寫入新位置。
- 刪除源列。
由于 EPPlus 沒有直接插入列的方法,我們可以通過 將目標(biāo)列及之后的所有列向右移動(dòng)一格 來模擬插入。
// C# 示例
using OfficeOpenXml;
using System.IO;
using System.Linq;
class Program
{
static void Main()
{
ExcelPackage.LicenseContext = LicenseContext.NonCommercial; // 開源許可
using var package = new ExcelPackage(new FileInfo("input.xlsx"));
var sheet = package.Workbook.Worksheets[0];
// 將第 3 列移動(dòng)到第 1 列(1-based 索引)
MoveColumn(sheet, 3, 1);
package.SaveAs(new FileInfo("output.xlsx"));
}
static void MoveColumn(ExcelWorksheet sheet, int sourceCol, int targetCol)
{
if (sourceCol == targetCol) return;
int maxRow = sheet.Dimension.Rows;
// 步驟1:讀取源列數(shù)據(jù)
var sourceData = new object[maxRow];
for (int row = 1; row <= maxRow; row++)
{
sourceData[row - 1] = sheet.Cells[row, sourceCol].Value;
}
// 步驟2:插入空白列到目標(biāo)位置
// 將 targetCol 及之后的所有列向右移動(dòng)一列(從右向左移動(dòng)避免覆蓋)
int lastCol = sheet.Dimension.Columns;
for (int col = lastCol; col >= targetCol; col--)
{
for (int row = 1; row <= maxRow; row++)
{
sheet.Cells[row, col + 1].Value = sheet.Cells[row, col].Value;
}
}
// 步驟3:將源列數(shù)據(jù)寫入新的目標(biāo)列
for (int row = 1; row <= maxRow; row++)
{
sheet.Cells[row, targetCol].Value = sourceData[row - 1];
}
// 步驟4:刪除原始列
// 如果源列在目標(biāo)列之后,刪除時(shí)需要調(diào)整索引(因?yàn)橐呀?jīng)插入了一列)
int colToDelete = sourceCol >= targetCol ? sourceCol + 1 : sourceCol;
for (int row = 1; row <= maxRow; row++)
{
for (int col = colToDelete; col < sheet.Dimension.Columns; col++)
{
sheet.Cells[row, col].Value = sheet.Cells[row, col + 1].Value;
}
}
// 刪除最后一列(已經(jīng)空了)
sheet.DeleteColumn(sheet.Dimension.Columns);
}
}說明:
- EPPlus 刪除列需要手動(dòng)移位,上述代碼通過循環(huán)向前覆蓋然后刪除最后一列來實(shí)現(xiàn)。
- 對于大表格,此方法效率較低,建議使用商業(yè)庫如 Aspose.Cells 或 Spire.XLS。
方法三:使用 Open XML SDK(官方庫,無需第三方依賴)
Open XML SDK 直接操作 Excel 文件的 XML 結(jié)構(gòu),性能最好但代碼量最大。下面給出 C# 示例的核心邏輯。
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
void MoveColumnInOpenXml(string filePath, int sourceCol, int targetCol)
{
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, true))
{
WorkbookPart workbookPart = doc.WorkbookPart;
WorksheetPart worksheetPart = workbookPart.WorksheetParts.First();
Worksheet worksheet = worksheetPart.Worksheet;
SheetData sheetData = worksheet.GetFirstChild<SheetData>();
// 讀取所有行,并重新排列單元格順序
foreach (Row row in sheetData.Elements<Row>())
{
var cells = row.Elements<Cell>().ToList();
if (cells.Count == 0) continue;
// 找到源列和目標(biāo)列的 Cell 對象(根據(jù)列索引轉(zhuǎn)換 A,B,C...)
// 注意:Open XML 中單元格引用可能不連續(xù),需要處理缺失單元格
// 建議使用輔助方法將列號轉(zhuǎn)換為列名,再通過 CellReference 定位
// 這里省略具體實(shí)現(xiàn),因?yàn)榇a較冗長。完整實(shí)現(xiàn)需要:
// 1. 獲取源列和目標(biāo)列的 Cell(如果不存在則創(chuàng)建空 Cell)
// 2. 交換兩者的值、數(shù)據(jù)類型、樣式等屬性
// 3. 調(diào)整單元格的引用位置
}
worksheet.Save();
}
}優(yōu)點(diǎn):完全免費(fèi),無外部依賴。
缺點(diǎn):需要深入理解 Excel Open XML 結(jié)構(gòu),處理合并單元格、公式、樣式等非常復(fù)雜。
總結(jié)
本文介紹了如何在 C# 和 VB.NET 中以編程方式重新排列 Excel 工作表中的列順序。通過創(chuàng)建臨時(shí)工作表并結(jié)合列復(fù)制操作,可以靈活地按照指定順序調(diào)整列的位置,同時(shí)保留原有數(shù)據(jù)和列寬設(shè)置。
這種方法適用于需要批量整理表格結(jié)構(gòu)、優(yōu)化數(shù)據(jù)展示順序或自動(dòng)化處理 Excel 文件的場景。相比手動(dòng)拖動(dòng)列的方式,程序化處理在面對大量文件時(shí)更加高效,也更便于集成到數(shù)據(jù)處理或報(bào)表生成流程中。
到此這篇關(guān)于C#代碼實(shí)現(xiàn)重新排列Excel中的列的文章就介紹到這了,更多相關(guān)C#重新排列Excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
UnityShader3實(shí)現(xiàn)2D描邊效果
這篇文章主要為大家詳細(xì)介紹了UnityShader3實(shí)現(xiàn)2D描邊效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
Unity3D運(yùn)行報(bào)DllNotFoundException錯(cuò)誤的解決方案
這篇文章主要介紹了Unity3D運(yùn)行報(bào)DllNotFoundException錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04
C#連接SQL數(shù)據(jù)庫和查詢數(shù)據(jù)功能的操作技巧
本文給大家分享C#連接SQL數(shù)據(jù)庫和查詢數(shù)據(jù)功能的操作技巧,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),需要的朋友參考下吧2021-05-05
C#中Foreach循環(huán)遍歷的本質(zhì)與枚舉器詳解
這篇文章主要給大家介紹了關(guān)于C#中Foreach循環(huán)遍歷本質(zhì)與枚舉器的相關(guān)資料,foreach循環(huán)用于列舉出集合中所有的元素,foreach語句中的表達(dá)式由關(guān)鍵字in隔開的兩個(gè)項(xiàng)組成,本文通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-08-08
C# 漢字轉(zhuǎn)拼音實(shí)例(支持GB2312字符集中所有漢字)
本篇文章主要介紹了C# 漢字轉(zhuǎn)拼音實(shí)例(支持GB2312字符集中所有漢字) ,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。2016-12-12

