• 使用OpenXML将数据导入到Excel模板中


    前言

    之前文章中简单的介绍过将数据导入到excel中,在日常的工作的很多时候其实我们是需要将数据导入到指定的模板的。其实将数据导入到模板和将数据导入到新的Excel模板中没有多大的区别。本文主要介绍导入到模板应该注意的一些地方。

    准备工作

    1.Excel模板如下:

    image

    2.openxml相关类库:

    image

    3.控制台或者winform程序

    注意事项

    1.因为是导入到现有Excel模板,所以使用SpreadsheetDocument.Open(filePath, true)打开Excel文档;

    1 using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, true))
    2 {
    3 //TODO:
    4 }

    2.插入数据前需要先获取待插入Excel的WorksheetPart,SheetData,以获取当前Excel中的行信息和插入数据用;

    1 WorkbookPart workbook = document.WorkbookPart;
    2
    3 WorksheetPart worksheet = workbook.WorksheetParts.Last();
    4
    5 SheetData sheetData = worksheet.Worksheet.GetFirstChild<SheetData>();
    6
    7 Sheets sheets = workbook.Workbook.Sheets;

    3.获取数据行的样式索引(StyleIndex),使得新添加行的样式能够匹配已有数据行样式(下面代码仅为示意);

    1 //记录第二行样式
    2 IEnumerable<Row> excelRows = worksheet.Worksheet.Descendants<Row>();
    3
    4 Row firstRow = excelRows.FirstOrDefault(r => r.RowIndex == 2);
    5
    6 UInt32 styleIndex = firstRow.RowIndex;


    4.由于DataTable中数据列和表格中列不一定统一,这里就需要采取一定措施使得插入数据的正确性。本人采取的是比较笨得方式,定义一个同模板列顺序一致的枚举(枚举出所有的列名,列名是dataTable中的列名,枚举值是模板中列的单元格列索引)。根据枚举值获取待插入Cell,然后向指定Cell中插入数据;

    如:DataTable的列为:ItemNo,ItemDesc,PCS,GrossWT,Height,Length,Width,Package,ChargeWT,Fee

    则定义枚举以对应导出的列:

     1     public enum TestTemplateColumn
    2 {
    3 ItemNo,
    4 ItemDesc,
    5 PCS,
    6 GrossWT,
    7 Length,
    8 Width,
    9 Height,
    10 ChargeWT,
    11 Fee,
    12 Package
    13 }

    5.创建Row时RowIndex注意不能重复,否则文档出错。另外,新创建的Row一定要添加到SheetData中 ,否则数据不会保存到Excel中;

    1 Row row = excelRows.FirstOrDefault(r => r.RowIndex == rowIndex + 3);
    2
    3 if (row == null)
    4 {
    5 row = new Row();
    6 row.RowIndex = (UInt32)rowIndex + 3;//第一行,第二行为标题行
    7 sheetData.AppendChild(row);
    8 }


    6.如果需要也可以修改Excel的SheetName,如将”Sheet1”修改为“Test”

    1 Sheets sheets = workbook.Workbook.Sheets;
    2
    3 Sheet sheet = sheets.GetFirstChild<Sheet>();
    4
    5 sheet.Name = "Test";

    上述注意事项,是在使用OpenXML将DataTable数据导入到模板中, 总结出来的,不一定很全,还望补充。

    (部分示例代码如下)

    View Code
     1  private void InsertDataToExcel(DataTable dt, string filePath,string sheetName)
    2 {
    3 using (SpreadsheetDocument document = SpreadsheetDocument.Open(filePath, true))
    4 {
    5 WorkbookPart workbook = document.WorkbookPart;
    6 WorksheetPart worksheet = workbook.WorksheetParts.Last();
    7 SheetData sheetData = worksheet.Worksheet.GetFirstChild<SheetData>();
    8
    9 Sheets sheets = workbook.Workbook.Sheets;
    10 Sheet sheet = sheets.GetFirstChild<Sheet>();
    11
    12 if (string.IsNullOrEmpty(sheetName))
    13 {
    14 sheet.Name = sheetName;
    15 }
    16
    17 IEnumerable<Row> excelRows = worksheet.Worksheet.Descendants<Row>();
    18
    19 Row firstRow = excelRows.FirstOrDefault(r => r.RowIndex == 2);
    20 IEnumerable<Cell> firstCells = firstRow.Descendants<Cell>();
    21
    22 UInt32 styleIndex = 0;
    23 for(int rowIndex =0;rowIndex< dt.Rows.Count;rowIndex++)
    24 {
    25 Row row = excelRows.FirstOrDefault(r => r.RowIndex == rowIndex + 3);
    26
    27 if (row == null)
    28 {
    29 row = new Row();
    30 row.RowIndex = (UInt32)rowIndex + 3;//第一行,第二行为标题行
    31 sheetData.AppendChild(row);
    32 }
    33
    34 IEnumerable<Cell> cells = row.Descendants<Cell>();
    35
    36 //具体插入代码省略了主要两步
    37
    38 //1. 先获取单元格
    39
    40 //2 .将数据插入单元格中
    41 }
    42 }
    43 }
    44
    45
    46 private Cell GetCell(RateColumn column, Row row, IEnumerable<Cell> cells)
    47 {
    48 Cell cell = null;
    49 string cellRef = GetCellReference((int)column+1) + row.RowIndex;
    50 cell = cells.FirstOrDefault(cel => cel.CellReference == cellRef);
    51 return cell;
    52 }
    53
    54 private void InsertCell(RateColumn column, Row row, object value, Cell cell,uint? styleIndex)
    55 {
    56 string strValue = value == null ? string.Empty : value.ToString();
    57 int rowIndex = int.Parse(row.RowIndex.ToString());
    58 if (cell == null)
    59 {
    60 double val = 0;
    61 if (double.TryParse(strValue, out val))
    62 {
    63 cell = CreateValueCell((int)column, rowIndex, val, styleIndex);
    64 }
    65 else
    66 {
    67 cell = CreateTextCell((int)column, rowIndex, strValue, styleIndex);
    68 }
    69 row.AppendChild(cell);
    70 }
    71 else
    72 {
    73 double val = 0;
    74 if (double.TryParse(strValue, out val))
    75 {
    76 cell.CellValue = new CellValue();
    77 cell.CellValue.Text = strValue;
    78 }
    79 else
    80 {
    81 InlineString inlineString = new InlineString();
    82 Text t = new Text();
    83 t.Text = strValue;
    84 cell.DataType = CellValues.InlineString;
    85 cell.InlineString = inlineString;
    86 cell.InlineString.Text = t;
    87 }
    88 }
    89 }
  • 相关阅读:
    go.mod
    数据库工具Navicat 更换(null)数据
    Debian 开启 BBR 算法
    @BeforeTest、@BeforeSuit等注解的区别
    推荐一个不错的非常漂亮的天气预报网站:tianqi.ipip5.com
    一条sql语句完成MySQL去重留保留一条记录
    php随机打乱数组顺序保留键值(php对数组洗牌算法实现)
    推荐一个不错的汉字笔顺查询网站https://bishun.ipip5.com
    使用NSSM把.Net Core部署至 Windows 服务
    通过 .NET NativeAOT 实现用户体验升级
  • 原文地址:https://www.cnblogs.com/pszw/p/2334679.html
Copyright © 2020-2023  润新知