【问题标题】:Add Dropdown Validation to an entire Excel Column using OpenXML使用 OpenXML 将下拉验证添加到整个 Excel 列
【发布时间】:2022-05-06 10:30:10
【问题描述】:

在 Excel 中,我可以向一系列单元格添加验证规则,并将接受的输入限制为下拉列表中显示的值列表。这是使用数据验证工具完成的,如下图所示:

我有一些 C# 代码可以生成一个 Excel 工作表,我想将这种相同类型的验证添加到其中一列。

使用Microsoft.Office.Interop.Excel,我可以将这种下拉验证添加到整个列:

string flatList = "FirstChoice,SecondChoice,ThirdChoice";

//select the entire first row as the range
Microsoft.Office.Interop.Excel.Range range = worksheet.get_Range("A1").EntireColumn;

//remove any previously existing validation           
range.Validation.Delete();               

//add new validation
range.Validation.Add(
    Microsoft.Office.Interop.Excel.XlDVType.xlValidateList,
    Microsoft.Office.Interop.Excel.XlDVAlertStyle.xlValidAlertInformation,
    Microsoft.Office.Interop.Excel.XlFormatConditionOperator.xlBetween,
    flatList,
    Type.Missing);

range.Validation.IgnoreBlank = true;
range.Validation.InCellDropdown = true;

问题是,我不能保证我的用户安装了 Microsoft Office。因此,我想改用DocumentFormat.OpenXML

是否可以使用 OpenXML 添加相同类型的下拉验证?

我看过一些使用 DataValidation 的帖子,但还没有弄清楚如何让它工作,以及这是否能解决我的问题。

【问题讨论】:

    标签: c# excel validation office-interop openxml


    【解决方案1】:

    通过更多的挖掘,我能够弄清楚如何使用DataValidation 在我的 Excel 工作表中使用DocumentFormat.OpenXml 向整个列添加下拉验证:

    string flatList = "FirstChoice,SecondChoice,ThirdChoice";
    
    DataValidation dataValidation = new DataValidation
    {
        Type = DataValidationValues.List,
        AllowBlank = true,
    
        //Use A:A or A1:A1048576 to select the entire column A
        //1048576 (2^20) is the max row number since Excel 2007.
        SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A:A" },
    
        //Set the formula to the list of dropdown values. Escape the double quotes.
        Formula1 = new Formula1("\"" + flatList + "\"")
    };
    
    //Check if there are any other DataValidations already in the worksheet
    DataValidations dvs = worksheet.GetFirstChild<DataValidations>();
    if (dvs != null)
    {
        //If you already have existing validation for column A, you may need to Remove()
        //or Replace() the current validation to get the new validation to show.          
    
        //Add the new DataValidation to the list of DataValidations
        dvs.Count = dvs.Count + 1;
        dvs.Append(dataValidation);
    }
    else
    {
        DataValidations newDVs = new DataValidations();
        newDVs.Append(dataValidation);
        newDVs.Count = 1;
    
        //Append the validation to the DocumentFormat.OpenXml.SpreadSheet.Worksheet variable
        worksheet.Append(newDVs);
    }
    

    【讨论】:

    • 这不适用于引用整列的正常方法吗?例如A:A 而不是 A1:A1048576
    • @RogerN 是的,这确实有效。谢谢!更新了我的解决方案。
    • 这段代码对我来说不起作用,我必须在页边距级别附加我的dataValidations 才能使其正常工作。像这样:mysheet.InsertBefore(dataValidations, mysheet.Descendants&lt;PageMargins&gt;().FirstOrDefault());
    • @JamshaidK。很高兴你发布了这个。我有一个现有文件,并且没有任何代码可用于向现有文档添加验证。除了您发布的关于将其添加到工作表的 PageMargins 中的代码。
    • @goroth,我了解它造成的压力,它甚至没有通知您为什么 excel 没有加载。您也可能不想多次插入 dataValidations。对我来说,当我多次添加 dataValidation 时,这让我有点困难。而是获取相同的 dataValidations 对象,对其进行更改并在 excel 中进行更新。
    【解决方案2】:

    您说得对,您需要使用 DataValidation 类,但您也需要 DataValidations 类。

    WorkSheet 可以有零个或一个DataValidations,而DataValidations 又可以包含一个或多个DataValidation

    以下代码将创建您正在寻找的数据验证:

    using (SpreadsheetDocument myDoc = SpreadsheetDocument.Create(filename, SpreadsheetDocumentType.Workbook))
    {
        /*** GENERAL SETUP ***/
        WorkbookPart workbookpart = myDoc.AddWorkbookPart();
        workbookpart.Workbook = new Workbook();
        // Add a WorksheetPart to the WorkbookPart.
        WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
        SheetData sheetData = new SheetData();
        // Add a WorkbookPart to the document.
        worksheetPart.Worksheet = new Worksheet(sheetData);
        Sheets sheets = myDoc.WorkbookPart.Workbook.AppendChild(new Sheets());
        sheets.AppendChild(new Sheet()
        {
            Id = myDoc.WorkbookPart.GetIdOfPart(myDoc.WorkbookPart.WorksheetParts.First()),
            SheetId = 1,
            Name = "Sheet1"
        });
    
        /***  DATA VALIDATION CODE ***/
        DataValidations dataValidations = new DataValidations();
        DataValidation dataValidation = new DataValidation() 
        { 
            Type = DataValidationValues.List, 
            AllowBlank = true,
            SequenceOfReferences = new ListValue<StringValue>() { InnerText = "A1:A1048576" }
        };
        Formula1 formula = new Formula1();
        formula.Text = "\"FirstChoice,SecondChoice,ThirdChoice\"";
    
        dataValidation.Append(formula);
        dataValidations.Append(dataValidation);
    
        worksheetPart.Worksheet.AppendChild(dataValidations);
    }
    

    【讨论】:

      【解决方案3】:

      我能够获得手动下拉菜单,并且我正在研究以获得动态 excel。我能够弄清楚如何使用 DataValidation 使用 DocumentFormat.OpenXml 将下拉验证添加到我的 Excel 工作表中的整个列。

      public class DataInSheet
          {
              public string firstRow { get; set; }
      
              internal static IEnumerable<object> GetDataOfSheet()
              {
                  List<DataInSheet> dataForSheet = new List<DataInSheet>
                  {
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                      new DataInSheet
                      {
                          firstRow  = "Sanjay"
                      },
                  };
                  return dataForSheet;
              }
          }
      
          public static void CreateExcelWithDynamicHeader(string fileName, List<string> headerFields, string sheetName, string dropDownItems)
          {
              using (SpreadsheetDocument document = SpreadsheetDocument.Create(fileName, SpreadsheetDocumentType.Workbook))
              {
                  WorkbookPart workbookPart = document.AddWorkbookPart();
                  workbookPart.Workbook = new Workbook();
      
                  WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>();
                  worksheetPart.Worksheet = new Worksheet(new SheetData());
      
                  WorksheetPart worksheetPart2 = workbookPart.AddNewPart<WorksheetPart>();
                  worksheetPart2.Worksheet = new Worksheet(new SheetData());
      
                  Sheets sheets = document.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());
      
                  //sheets.Append(sheets);
      
                  Worksheet worksheet1 = new Worksheet()
                  { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
                  worksheet1.AddNamespaceDeclaration
                  ("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                  worksheet1.AddNamespaceDeclaration
                  ("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                  worksheet1.AddNamespaceDeclaration
                  ("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
      
                  Worksheet worksheet2 = new Worksheet()
                  { MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "x14ac" } };
                  worksheet2.AddNamespaceDeclaration
                  ("r", "http://schemas.openxmlformats.org/officeDocument/2006/relationships");
                  worksheet2.AddNamespaceDeclaration
                  ("mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
                  worksheet2.AddNamespaceDeclaration
                  ("x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
      
      
                  Sheet sheet = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
      
                  Sheet sheet1 = new Sheet() { Id = document.WorkbookPart.GetIdOfPart(worksheetPart2), SheetId = 2, Name = dropDownItems };
      
                  sheets.Append(sheet);
                  sheets.Append(sheet1);
                  //document.WorkbookPart.Workbook.Save();
                  SheetData sheetData = new SheetData();
                  SheetData sheetData1 = new SheetData();
      
                  double width = 6;
                  // Constructing header
                  Row headerRow = new Row();
                  for (int i = 0; i < headerFields.Count; i++)
                  {
                      if (width < headerFields[i].Length)
                      {
                          width = headerFields[i].Length;
                      }
      
                      Columns columns = new Columns();
                      columns.Append(new Column() { Min = 1, Max = (UInt32)headerFields.Count, Width = width, CustomWidth = true });
      
                      worksheetPart.Worksheet.Append(columns);
                      Cell cell = new Cell();
                      cell.DataType = CellValues.String;
                      cell.CellValue = new CellValue(headerFields[i]);
      
                      headerRow.AppendChild(cell);
                  }
                  sheetData.AppendChild(headerRow);
                  worksheet1.Append(sheetData);
      
                  int Counter = 1;
                  foreach (var value in DataInSheet.GetDataOfSheet())
                  {
      
                      Row contentRow = CreateRowValues(Counter, value);
                      Counter++;
                      sheetData1.AppendChild(contentRow);
                  }
                  worksheet2.Append(sheetData1);
      
      
                  DataValidation dataValidation = new DataValidation
                  {
                      Type = DataValidationValues.List,
                      AllowBlank = true,
                      SequenceOfReferences = new ListValue<StringValue>() { InnerText = "B1" },
                      //Formula1 = new Formula1("'Import Face'!$A$1:$A$6")
                      Formula1 = new Formula1("'DropDownDataContainingSheet'!$A:$A")
                  };
      
                  DataValidations dataValidations = worksheet1.GetFirstChild<DataValidations>();
                  if (dataValidations != null)
                  {
                      dataValidations.Count = dataValidations.Count + 1;
                      dataValidations.Append(dataValidation);
                  }
                  else
                  {
                      DataValidations newdataValidations = new DataValidations();
                      newdataValidations.Append(dataValidation);
                      newdataValidations.Count = 1;
                      worksheet1.Append(newdataValidations);
                  }
                  worksheetPart.Worksheet = worksheet1; ;
                  worksheetPart2.Worksheet = worksheet2;
                  workbookPart.Workbook.Save();
                  document.Close();
              }
          }
      
          static string[] headerColumns = new string[] { "A", "B", "C", "D" };
          private static Row CreateRowValues(int index, object value)
          {
              Row row = new Row();
              row.RowIndex = (UInt32)index;
              int i = 0;
              foreach (var property in value.GetType().GetProperties())
              {
                  Cell cell = new Cell();
                  cell.CellReference = headerColumns[i].ToString() + index;
                  if (property.PropertyType.ToString()
                  .Equals("System.string", StringComparison.InvariantCultureIgnoreCase))
                  {
      
                      var result = property.GetValue(value, null);
                      if (result == null)
                      {
                          result = "";
                      }
                      cell.DataType = CellValues.String;
                      InlineString inlineString = new InlineString();
                      Text text = new Text();
                      text.Text = result.ToString();
                      inlineString.AppendChild(text);
                      cell.AppendChild(inlineString);
                  }
                  if (property.PropertyType.ToString()
                  .Equals("System.int32", StringComparison.InvariantCultureIgnoreCase))
                  {
                      var result = property.GetValue(value, null);
                      if (result == null)
                      {
                          result = 0;
                      }
                      CellValue cellValue = new CellValue();
                      cellValue.Text = result.ToString();
                      cell.AppendChild(cellValue);
                  }
                  if (property.PropertyType.ToString()
                  .Equals("System.boolean", StringComparison.InvariantCultureIgnoreCase))
                  {
                      var result = property.GetValue(value, null);
                      if (result == null)
                      {
                          result = "False";
                      }
                      cell.DataType = CellValues.InlineString;
                      InlineString inlineString = new InlineString();
                      Text text = new Text();
                      text.Text = result.ToString();
                      inlineString.AppendChild(text);
                      cell.AppendChild(inlineString);
                  }
      
                  row.AppendChild(cell);
                  i = i + 1;
              }
              return row;
          }
      

      【讨论】:

      • 不鼓励使用纯代码的答案。请单击edit 并添加一些词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。谢谢
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-23
      • 1970-01-01
      • 1970-01-01
      • 2016-10-09
      • 2017-06-15
      相关资源
      最近更新 更多