使用 OpenXML 从 Excel 中删除公式
Removing a formula from Excel using OpenXML
我正在尝试使用 openxml 从 sheet 中删除所有公式。这就是我正在尝试的:
internal static void ReplaceFormulaWithValue()
{
var res = _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>();
foreach (Row row in _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellFormula != null &&
cell.CellValue != null)
{
string cellRef = cell.CellReference;
CalculationChainPart calculationChainPart = _spreadSheet.WorkbookPart.CalculationChainPart;
CalculationChain calculationChain = calculationChainPart.CalculationChain;
var calculationCells = calculationChain.Elements<CalculationCell>().ToList();
CalculationCell calculationCell = calculationCells.Where(c => c.CellReference == cellRef).FirstOrDefault();
//CalculationCell calculationCell = calculationChain.Elements<CalculationCell>().Where(c => c.CellReference == cell.CellReference).FirstOrDefault();
string value = cell.CellValue.InnerText;
UpdateCell(cell, DataTypes.String, value);
cell.CellFormula.Remove();
calculationCell.Remove();
}
}
}
SaveChanges();
}
打开 excel 文档后,我收到以下错误消息:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>error192600_01.xml</logFileName><summary>Errors were detected in file 'C:\DEV\ExcelEditor\ExcelEditor\bin\Debug\Chart.xlsx'</summary>
<removedParts summary="Following is a list of removed parts:">
<removedPart>Removed Part: /xl/calcChain.xml part with XML error. (Calculation properties) Catastrophic failure Line 1, column 138.</removedPart>
</removedParts></recoveryLog>
因此,我将旧 calcChain.xml 文件与使用 OpenXML SDK 工具新生成的文件进行比较。旧文件具有以下内容:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<calcChain xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<c i="1" l="1" r="D2"/>
</calcChain>
和 运行 之后的新代码我的代码:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<x:calcChain xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
</x:calcChain>
如果我遗漏了什么,谁能帮忙。
如果要删除所有公式,为什么需要空calcChain.xml?你试过删除它吗?
这对我有用:
public static void ReplaceFormulasWithValue()
{
try
{
CalculationChainPart calculationChainPart = _spreadSheet.WorkbookPart.CalculationChainPart;
CalculationChain calculationChain = calculationChainPart.CalculationChain;
var calculationCells = calculationChain.Elements<CalculationCell>().ToList();
foreach (Row row in _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellFormula != null && cell.CellValue != null)
{
string cellRef = cell.CellReference;
CalculationCell calculationCell = calculationCells.Where(c => c.CellReference == cellRef).FirstOrDefault();
UpdateCell(cell, DataTypes.String, cell.CellValue.InnerText);
cell.CellFormula.Remove();
if(calculationCell != null)
{
calculationCell.Remove();
calculationCells.Remove(calculationCell);
}
else
{
//Something is went wrong - log it
}
}
if (calculationCells.Count == 0)
_spreadSheet.WorkbookPart.DeletePart(calculationChainPart);
}
_worksheetPart.Worksheet.Save();
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
我正在尝试使用 openxml 从 sheet 中删除所有公式。这就是我正在尝试的:
internal static void ReplaceFormulaWithValue()
{
var res = _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>();
foreach (Row row in _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellFormula != null &&
cell.CellValue != null)
{
string cellRef = cell.CellReference;
CalculationChainPart calculationChainPart = _spreadSheet.WorkbookPart.CalculationChainPart;
CalculationChain calculationChain = calculationChainPart.CalculationChain;
var calculationCells = calculationChain.Elements<CalculationCell>().ToList();
CalculationCell calculationCell = calculationCells.Where(c => c.CellReference == cellRef).FirstOrDefault();
//CalculationCell calculationCell = calculationChain.Elements<CalculationCell>().Where(c => c.CellReference == cell.CellReference).FirstOrDefault();
string value = cell.CellValue.InnerText;
UpdateCell(cell, DataTypes.String, value);
cell.CellFormula.Remove();
calculationCell.Remove();
}
}
}
SaveChanges();
}
打开 excel 文档后,我收到以下错误消息:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<recoveryLog xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<logFileName>error192600_01.xml</logFileName><summary>Errors were detected in file 'C:\DEV\ExcelEditor\ExcelEditor\bin\Debug\Chart.xlsx'</summary>
<removedParts summary="Following is a list of removed parts:">
<removedPart>Removed Part: /xl/calcChain.xml part with XML error. (Calculation properties) Catastrophic failure Line 1, column 138.</removedPart>
</removedParts></recoveryLog>
因此,我将旧 calcChain.xml 文件与使用 OpenXML SDK 工具新生成的文件进行比较。旧文件具有以下内容:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<calcChain xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
<c i="1" l="1" r="D2"/>
</calcChain>
和 运行 之后的新代码我的代码:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<x:calcChain xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
</x:calcChain>
如果我遗漏了什么,谁能帮忙。
如果要删除所有公式,为什么需要空calcChain.xml?你试过删除它吗?
这对我有用:
public static void ReplaceFormulasWithValue()
{
try
{
CalculationChainPart calculationChainPart = _spreadSheet.WorkbookPart.CalculationChainPart;
CalculationChain calculationChain = calculationChainPart.CalculationChain;
var calculationCells = calculationChain.Elements<CalculationCell>().ToList();
foreach (Row row in _worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements<Row>())
{
foreach (Cell cell in row.Elements<Cell>())
{
if (cell.CellFormula != null && cell.CellValue != null)
{
string cellRef = cell.CellReference;
CalculationCell calculationCell = calculationCells.Where(c => c.CellReference == cellRef).FirstOrDefault();
UpdateCell(cell, DataTypes.String, cell.CellValue.InnerText);
cell.CellFormula.Remove();
if(calculationCell != null)
{
calculationCell.Remove();
calculationCells.Remove(calculationCell);
}
else
{
//Something is went wrong - log it
}
}
if (calculationCells.Count == 0)
_spreadSheet.WorkbookPart.DeletePart(calculationChainPart);
}
_worksheetPart.Worksheet.Save();
}
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}