使用OpenXml将文本写入特定的Excel单元时遇到问题 - c#

我要实现的目标如下所示:

使用OpenXml将文本写入特定的Excel单元时遇到问题 - c#

我遇到的结果和问题如下所示:

这是我的代码生成的结果文件,应该有预期的内容。

使用OpenXml将文本写入特定的Excel单元时遇到问题 - c#

单击“是”按钮后的窗口提示。

使用OpenXml将文本写入特定的Excel单元时遇到问题 - c#

我的运行代码如下:

主要方法:

public static void Main(string[] args)
{
    WriteExcelService writeExcelService = new WriteExcelService();
    Dictionary<string, List<string>> contentList = new Dictionary<string, List<string>>
    {
        { "en-US",new List<string> (new string[] { "Dummy text 01","Dummy text 02"}) },
        { "es-ES",new List<string> (new string[] { "Texto ficticio 01", "Texto ficticio 02"}) }
    };
    string inputFile = @"C:\{username}\Desktop\Valentines_Day.xlsx";
    string sheetName = "Copy";

    writeExcelService.WriteValueToCell(inputFile, sheetName, contentList);
}

WriteValueToCell方法:

char columnName = 'I';
        uint rowNumber = 1;
        foreach (var keys in contentList.Keys)
        {
            foreach (var value in contentList.Where(v => v.Key == keys).SelectMany(v => v.Value))
            {
                string cellAddress = String.Concat(columnName, rowNumber);
                this.Write(filepath, sheetName, value, cellAddress, rowNumber);
                int tempColumn = (int)columnName;
                columnName = (char)++tempColumn;
            }
            columnName = 'I';
            ++rowNumber;
        }

写入方法:

private void Write(string filepath, string sheetName, string value, string cellAddress,uint rowNumber)
{
    // Create a spreadsheet document by supplying the filepath.
    // By default, AutoSave = true, Editable = true, and Type = xlsx.
    using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
    {
        //writeExcelService.WriteValueToCell(outputFilePath, sheetName, cellAddress, value.Value);
        // Add a WorkbookPart to the document.
        WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart();
        workbookpart.Workbook = new Workbook();

        // Add a WorksheetPart to the WorkbookPart.
        WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>();
        worksheetPart.Worksheet = new Worksheet(new SheetData());

        // Add Sheets to the Workbook.
        Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets());

        // Append a new worksheet and associate it with the workbook.
        Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = sheetName };
        sheets.Append(sheet);

        // Get the sheetData cell table.
        SheetData sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();

        // Add a row to the cell table.
        Row row;
        row = new Row() { RowIndex = rowNumber };
        sheetData.Append(row);

        // In the new row, find the column location to insert a cell.
        Cell refCell = null;
        foreach (Cell cell in row.Elements<Cell>())
        {
            if (string.Compare(cell.CellReference.Value, cellAddress, true) > 0)
            {
                refCell = cell;
                break;
            }
        }

        // Add the cell to the cell table.
        Cell newCell = new Cell() { CellReference = cellAddress };
        row.InsertBefore(newCell, refCell);

        // Set the cell value to be a numeric value.
        newCell.CellValue = new CellValue(value);
        newCell.DataType = new EnumValue<CellValues>(CellValues.Number);
    }
}

我的问题是:

我的代码执行了,但是一旦打开结果文件,它会提示我上面发布的窗口,并且该文件为空。如果我调试代码以一一插入内容列表,则可以将其正确写入Cells I2J2。由于我的代码为每个列表内容创建了SpreadsheetDocument,因此,我在以下代码中更改了SpreadsheetDocument创建方法:

using (SpreadsheetDocument spreadsheetDocument = File.Exists(filePath) ?
SpreadsheetDocument.Open(filepath, true) : 
SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook))
   {

   }

但我越来越例外

该父级仅允许使用该类型的一个实例。

有人可以帮我吗?

提前欣赏一下。

参考方案

excel中的字符串保存在sharedStringTable下。插入字符串时,重要的是添加字符串或从sharedStringTable引用字符串。另外,您需要为单元格提供正确的DataType。在代码中,您将所有值插入为数字:

// Set the cell value to be a numeric value.
newCell.CellValue = new CellValue(value);
newCell.DataType = new EnumValue<CellValues>(CellValues.Number);

要插入字符串,我建议在创建新单元格后使用以下方法:

private SpreadsheetDocument _spreadSheet;
private WorksheetPart _worksheetPart;
..
..
private void UpdateCell(Cell cell, DataTypes type, string text)
{
    if (type == DataTypes.String)
    {
        cell.DataType = CellValues.SharedString;

        if (!_spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Any())
        {
            _spreadSheet.WorkbookPart.AddNewPart<SharedStringTablePart>();
        }

        var sharedStringTablePart = _spreadSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First();
        if (sharedStringTablePart.SharedStringTable == null)
        {
            sharedStringTablePart.SharedStringTable = new SharedStringTable();
        }
        //Iterate through shared string table to check if the value is already present.
        foreach (SharedStringItem ssItem in sharedStringTablePart.SharedStringTable.Elements<SharedStringItem>())
        {
            if (ssItem.InnerText == text)
            {
                cell.CellValue = new CellValue(ssItem.ElementsBefore().Count().ToString());
                return;
            }
        }
        // The text does not exist in the part. Create the SharedStringItem.
        var item = sharedStringTablePart.SharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
        cell.CellValue = new CellValue(item.ElementsBefore().Count().ToString());
    }
    else if (type == DataTypes.Number)
    {
        cell.CellValue = new CellValue(text);
        cell.DataType = CellValues.Number;
    }
    else if (type == DataTypes.DateTime)
    {

        cell.DataType = CellValues.Number;
        cell.StyleIndex = Convert.ToUInt32(_dateStyleIndex);

        DateTime dateTime = DateTime.Parse(text);
        double oaValue = dateTime.ToOADate();
        cell.CellValue = new CellValue(oaValue.ToString(CultureInfo.InvariantCulture));
    }
    _worksheetPart.Worksheet.Save();
}

Java string.hashcode()提供不同的值 - java

我已经在这个问题上停留了几个小时。我已经注释掉所有代码,认为这与数组超出范围有关,但是这种情况仍在发生。我正在尝试使用扫描仪从文件中读取输入,存储数据并稍后使用哈希码获取该数据。但是哈希值不断变化。public static void main(String[] args) { //only prior code is to access data char…

string.split(“ _(B”) - java

基本上,这行代码行不通,我不确定原因: String[] stringHolder = string.split("_(B"); 我收到此错误:索引3附近的未封闭组此行代码有效: String[] stringHolder = string.split("_B"); 因此,这使我相信它是由“(”引起的。有人可以告诉我如…

LeetCode题解水壶问题

给你一个装满水的 8 升满壶和两个分别是 5 升、3 升的空壶,请想个优雅的办法,使得其中一个水壶恰好装 4 升水,每一步的操作只能是倒空或倒满。题解:``` .js/** * 思路: * 每个容器有两个选择,比如:A,可以倒入B,或者倒入C * 同样,B可以倒入A,也可以倒入C * 那么每次就有8种可能 * * 每产生一种可能,顺着这种可能的结果,继续去遍…

在索引处的String数组中找到元素的子字符串 - java

main应该分解名字和姓氏并将姓氏存储在新数组中。我的代码中存在逻辑错误,因为这部分不打印。package names; import java.io.*; import java.util.*; public class names { public static void main(String[] args) throws FileNotFoundEx…

为什么要使用Func <string>而不是string? - c#

为什么要使用Func<string>而不是string?我的问题特别是关于this回购。有问题的行是22: private static Func<string> getToken = () => Environment.GetEnvironmentVariable("GitHubToken", Enviro…