使用 OpenXML 将下拉验证添加到整个 Excel 列

Add Dropdown Validation to an entire Excel Column using OpenXML

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

我有一些生成 excel sheet 的 C# 代码,我想将这种相同类型的验证添加到其中一列。

使用 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 的帖子,但无法弄清楚如何让它工作,以及这是否能解决我的问题。

你说得对,你也需要使用 DataValidation class but you'll also need the DataValidations class。

一个 WorkSheet 可以有零个或一个 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);
}

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

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);
}

我能够获得手动下拉菜单,并且正在研究以获得动态 excel。我能够使用 DocumentFormat.OpenXml.

弄清楚如何使用 DataValidation 向 Excel sheet 中的整个列添加下拉验证
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:$A")
                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;
    }