gpt4 book ai didi

c# - 使用 OpenXML 使用目录文件填充 Excel 工作表列

转载 作者:行者123 更新时间:2023-11-30 17:32:13 25 4
gpt4 key购买 nike

我有一个包含两个工作表的 Excel 工作簿,“旅游信息”和“文档”。在“文档”工作表中,我必须用目录中找到的所有文件名填写“扫描的文档”列。除了 Scanned Document 列之外,我不必填写任何其他列。我无法使用从单元格引用 C3 开始的文件名填充 Excel 工作表。你能帮我用文件名填充该列吗?

“文档”表是:

enter image description here

我的代码是:

//Open the Excel file in Read Mode using OpenXML
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(@"C:\TouristRecord.xlsx", true))
{
WorksheetPart documents = GetWorksheetPart(doc.WorkbookPart, "Documents");
Worksheet documentsWorksheet = documents.Worksheet;
IEnumerable<Row> documentsRows = documentsWorksheet.GetFirstChild<SheetData>().Descendants<Row>();

//Loop through the Worksheet rows
foreach (var files in Directory.GetFiles(@"C:\DocumentsFolder"))
{
foreach (Row row in documentsRows)
{
// I am unable to write logic to update the excel sheet value here.
}
}
doc.Save();
}

GetWorksheetPart 方法是:

public WorksheetPart GetWorksheetPart(WorkbookPart workbookPart, string sheetName)
{
string relId = workbookPart.Workbook.Descendants<Sheet>().First(s => sheetName.Equals(s.Name)).Id;
return (WorksheetPart)workbookPart.GetPartById(relId);
}

最佳答案

要将单元格添加到 C3,您需要创建一个新的 Cell 对象,为其分配 C3 的单元格引用,设置其值,然后将其添加到 Row 代表工作表上的第 3 行。我们可以将该逻辑包装到这样的方法中:

private void AddCellToRow(Row row, string value, string cellReference)
{
//the cell might already exist, if it does we should use it.
Cell cell = row.Descendants<Cell>().FirstOrDefault(c => c.CellReference == cellReference);
if (cell == null)
{
cell = new Cell();
cell.CellReference = cellReference;
}
cell.CellValue = new CellValue(value);
cell.DataType = CellValues.String;
row.Append(cell);
}

如果我们假设当前工作表有一组连续的行,那么编写内容的逻辑就非常简单:

  • 迭代文档中的每一行
  • 检查行索引是否大于 2(因为你想从 3 开始写)。如果是:
    • 获取第 3 个 Cell 或如果它不存在则创建它。
    • 将文件列表的第 n 个元素添加到 Cell
    • 递增n
  • 迭代文件列表中的剩余文件(因为文件可能多于原始文档中的行)。为每一个:
    • 添加一个新的
    • 将新的 Cell 添加到 Row 并将文件名作为单元格的值。

将其放入您最终得到的代码中:

using (SpreadsheetDocument doc = SpreadsheetDocument.Open(@"C:\TouristRecord.xlsx", true))
{
WorksheetPart documents = GetWorksheetPart(doc.WorkbookPart, "Documents");
//get the she sheetdata as that's where we need to add rows
SheetData sheetData = documents.Worksheet.GetFirstChild<SheetData>();
IEnumerable<Row> documentsRows = sheetData.Descendants<Row>();
//get all of the files into an array
var filenames = Directory.GetFiles(@"C:\DocumentsFolder");

if (filenames.Length > 0)
{
int currentFileIndex = 0;

// keep the row index in case the rowindex property is null anywhere
// the spec allows for it to be null, in which case the row
// index is one more than the previous row (or 1 if this is the first row)
uint currentRowIndex = 1;

foreach (var documentRow in documentsRows)
{
if (documentRow.RowIndex.HasValue)
{
currentRowIndex = documentRow.RowIndex.Value;
}
else
{
currentRowIndex++;
}

if (currentRowIndex <= 2)
{
//this is row 1 or 2 so we can ignore it
continue;
}

AddCellToRow(documentRow, filenames[currentFileIndex], "C" + currentRowIndex);

currentFileIndex++;

if (filenames.Length <= currentFileIndex)
{
// there are no more files so we can stop
break;
}
}

// now output any files we haven't already output. These will need a new row as there isn't one
// in the document as yet.
for (int i = currentFileIndex; i < filenames.Length; i++)
{
//there are more files than there were rows in the directory, add more rows
Row row = new Row();
currentRowIndex++;
row.RowIndex = currentRowIndex;

AddCellToRow(row, filenames[i], "C" + currentRowIndex);
sheetData.Append(row);
}
}
}

上面假设当前工作表有一组连续的行。这可能并不总是正确的,因为规范允许不将空行写入 XML。在这种情况下,您最终可能会在输出中出现空白。假设原始文件的第 1、2 和 5 行有数据;在那种情况下,foreach 会导致您跳过写入第 3 行和第 4 行。这可以通过检查循环内的 currentRowIndex 并为任何间隙添加新的 Row 来解决这可能会发生。我没有添加该代码,因为它很复杂,有损于答案的基本原理。

关于c# - 使用 OpenXML 使用目录文件填充 Excel 工作表列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46888973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com