我正在尝试更改现有word文件的数据。我在嵌入式Excel文件中操作数据方面取得了成功,但不知何故,这些数据并未在Word文件中使用。此外,在Excel文件中,我看到最后一行之前的绿色标记,可能表示最后一行仍未考虑数据。有人可以帮忙处理这个问题吗?
我确实提到了很多来自ericwhite.com / openxmldeveloper.org的链接,但没有运气。
代码如下:
public void ReplaceChartValues(string placeholderCaption, System.Data.DataTable chartData, string newCaption)
{
if (wordDocument != null)
{
try
{
ChartPart target = mainDocumentPart
.ChartParts
.Where(r => r
.ChartSpace
.GetFirstChild<Chart>()
.Title
.InnerText
.StartsWith(placeholderCaption)
)
.FirstOrDefault();
if (target != null)
{
target
.ChartSpace
.GetFirstChild<Chart>()
.Title
.ChartText
.RichText
.GetFirstChild<DocumentFormat.OpenXml.Drawing.Paragraph>()
.GetFirstChild<DocumentFormat.OpenXml.Drawing.Run>()
.Text
.Text = newCaption;
ExternalData externalData =
target
.ChartSpace
.Elements<ExternalData>()
.FirstOrDefault();
if (externalData != null)
{
EmbeddedPackagePart embeddedPackagePart =
(EmbeddedPackagePart)
target
.Parts
.Where(r => r.RelationshipId == externalData.Id)
.FirstOrDefault()
.OpenXmlPart;
if (embeddedPackagePart != null)
{
using (Stream stream = embeddedPackagePart.GetStream())
{
using (SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Open(stream, true))
{
DocumentFormat.OpenXml.Spreadsheet.Sheet worksheet = (DocumentFormat.OpenXml.Spreadsheet.Sheet)spreadsheetDocument
.WorkbookPart
.Workbook
.Sheets
.FirstOrDefault();
WorksheetPart worksheetPart = (WorksheetPart)
spreadsheetDocument
.WorkbookPart
.Parts
.Where(r => r.RelationshipId == worksheet.Id)
.FirstOrDefault()
.OpenXmlPart;
DocumentFormat.OpenXml.Spreadsheet.SheetData sheetData =
worksheetPart
.Worksheet
.Elements<DocumentFormat.OpenXml.Spreadsheet.SheetData>()
.FirstOrDefault();
var existingRows = sheetData
.Elements<DocumentFormat.OpenXml.Spreadsheet.Row>()
.Skip(1)
.ToArray();
for (int ctr = 0; ctr < existingRows.Length; ctr++)
{
sheetData
.RemoveChild<DocumentFormat.OpenXml.Spreadsheet.Row>(existingRows[ctr]);
}
for (int ctr = 0; ctr < chartData.Rows.Count; ctr++)
{
DocumentFormat.OpenXml.Spreadsheet.Row newRecord = new DocumentFormat.OpenXml.Spreadsheet.Row();
for (int ctr2 = 0; ctr2 < chartData.Columns.Count; ctr2++)
{
DocumentFormat.OpenXml.Spreadsheet.Cell newCell = new DocumentFormat.OpenXml.Spreadsheet.Cell();
DocumentFormat.OpenXml.Spreadsheet.CellValue newCellValue = new DocumentFormat.OpenXml.Spreadsheet.CellValue();
if (chartData.Columns[ctr2].DataType == typeof(DateTime))
{
newCellValue.Text = Convert.ToDateTime(chartData.Rows[ctr][ctr2]).ToString("MM/dd/yyyy");
newCell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.Date;
}
else if (chartData.Columns[ctr2].DataType == typeof(decimal))
{
newCellValue.Text = chartData.Rows[ctr][ctr2].ToString();
newCell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.Number;
}
else
{
newCellValue.Text = chartData.Rows[ctr][ctr2].ToString();
newCell.DataType = DocumentFormat.OpenXml.Spreadsheet.CellValues.String;
}
newCell.AppendChild(newCellValue);
newRecord.AppendChild(newCell);
}
sheetData.AppendChild(newRecord);
}
spreadsheetDocument.Save();
}
}
}
}
}
}
catch (Exception)
{
}
finally
{
// Save the document.
mainDocumentPart.Document.Save();
}
}
}
答案 0 :(得分:0)
花费了很多时间,这是帮助的代码:
public void ReplaceChartValuesLinearChart(string placeholderCaption, System.Data.DataTable chartData, string newCaption)
{
if (wordDocument != null)
{
try
{
// Get the exact Chart Part where Caption matches the place holder value.
ChartPart target = mainDocumentPart
.ChartParts
.Where(r => r
.ChartSpace
.GetFirstChild<Chart>()
.Title
.InnerText
.StartsWith(placeholderCaption)
)
.FirstOrDefault();
if (target != null)
{
// Set the new caption.
target
.ChartSpace
.GetFirstChild<Chart>()
.Title
.ChartText
.RichText
.GetFirstChild<DocumentFormat.OpenXml.Drawing.Paragraph>()
.GetFirstChild<DocumentFormat.OpenXml.Drawing.Run>()
.Text
.Text = newCaption;
// Update all NumberingCache values to reflect total number of records.
foreach (NumberingCache currentNumberingCache in target.ChartSpace.Descendants<NumberingCache>())
{
currentNumberingCache.PointCount = new PointCount() { Val = (DocumentFormat.OpenXml.UInt32Value)(UInt32)chartData.Rows.Count };
currentNumberingCache.RemoveAllChildren<NumericPoint>();
}
// Set the Numeric Point values with formats and add to the appropriate NumberingCache.
for (int ctr = 0; ctr < chartData.Rows.Count; ctr++)
{
// First Range - contains date.
NumericPoint newNumericPoint = new NumericPoint();
newNumericPoint.Index = new DocumentFormat.OpenXml.UInt32Value((uint)ctr);
newNumericPoint.FormatCode = "[$-409]ddmmmyyyy";
newNumericPoint.NumericValue = new NumericValue(chartData.Rows[ctr][0].ToString());
target
.ChartSpace
.Descendants<NumberingCache>()
.ToArray()[0]
.AppendChild(newNumericPoint);
// Third Range - contains date.
newNumericPoint = new NumericPoint();
newNumericPoint.Index = new DocumentFormat.OpenXml.UInt32Value((uint)ctr);
newNumericPoint.FormatCode = "[$-409]ddmmmyyyy";
newNumericPoint.NumericValue = new NumericValue(chartData.Rows[ctr][0].ToString());
target
.ChartSpace
.Descendants<NumberingCache>()
.ToArray()[2]
.AppendChild(newNumericPoint);
// Second Range - contains reference data.
if (chartData.Rows[ctr][2] != DBNull.Value)
{
newNumericPoint = new NumericPoint();
newNumericPoint.Index = new DocumentFormat.OpenXml.UInt32Value((uint)ctr);
newNumericPoint.FormatCode = "0.00%";
newNumericPoint.NumericValue = new NumericValue(chartData.Rows[ctr][2].ToString());
target
.ChartSpace
.Descendants<NumberingCache>()
.ToArray()[1]
.AppendChild(newNumericPoint);
}
// Second Range - contains current data.
if (chartData.Rows[ctr][3] != DBNull.Value)
{
newNumericPoint = new NumericPoint();
newNumericPoint.Index = new DocumentFormat.OpenXml.UInt32Value((uint)ctr);
newNumericPoint.FormatCode = "0.00%";
newNumericPoint.NumericValue = new NumericValue(chartData.Rows[ctr][3].ToString());
target
.ChartSpace
.Descendants<NumberingCache>()
.ToArray()[3]
.AppendChild(newNumericPoint);
}
}
// Update all variable length formula to point to updated number of rows.
foreach (var currentFormula in target.ChartSpace.Descendants<Formula>())
{
if (currentFormula.Text.Contains(":"))
{
currentFormula.Text =
currentFormula.Text.Substring(0, currentFormula.Text.LastIndexOf("$") + 1)
+ (chartData.Rows.Count + 1).ToString();
}
}
// Get handle to ExternalData for accessing embedded Excel document.
ExternalData externalData =
target
.ChartSpace
.Elements<ExternalData>()
.FirstOrDefault();
if (externalData != null)
{
// Get handle to Package Part containing excel document.
EmbeddedPackagePart embeddedPackagePart =
(EmbeddedPackagePart)
target
.Parts
.Where(r => r.RelationshipId == externalData.Id)
.FirstOrDefault()
.OpenXmlPart;
if (embeddedPackagePart != null)
{
// Get handle to Stream for modifying data.
using (Stream stream = embeddedPackagePart.GetStream())
{
// Open Excel for manipulation.
using (SpreadsheetDocument spreadsheetDocument =
SpreadsheetDocument.Open(stream, true))
{
// Get handle to first sheet.
DocumentFormat
.OpenXml
.Spreadsheet
.Sheet worksheet = (DocumentFormat.OpenXml.Spreadsheet.Sheet)
spreadsheetDocument
.WorkbookPart
.Workbook
.Sheets
.FirstOrDefault();
// Get handle to first worksheet.
WorksheetPart worksheetPart = (WorksheetPart)
spreadsheetDocument
.WorkbookPart
.Parts
.Where(r => r.RelationshipId == worksheet.Id)
.FirstOrDefault()
.OpenXmlPart;
// Set Table range on the first worksheet.
worksheetPart
.TableDefinitionParts
.FirstOrDefault()
.Table
.Reference
.Value = "A1:D" + (chartData.Rows.Count + 1).ToString();
// Get handle to access entire sheet data.
DocumentFormat
.OpenXml
.Spreadsheet
.SheetData sheetData =
worksheetPart
.Worksheet
.Elements<DocumentFormat.OpenXml.Spreadsheet.SheetData>()
.FirstOrDefault();
// Select all data rows.
var existingRows = sheetData
.Elements<DocumentFormat.OpenXml.Spreadsheet.Row>()
.Skip(1)
.ToArray();
// Remove all existing data rows.
for (int ctr = 0; ctr < existingRows.Length; ctr++)
{
sheetData
.RemoveChild<DocumentFormat.OpenXml.Spreadsheet.Row>(existingRows[ctr]);
}
// Create new rows.
for (int ctr1 = 0; ctr1 < chartData.Rows.Count; ctr1++)
{
DocumentFormat
.OpenXml
.Spreadsheet
.Row newRecord = new
DocumentFormat
.OpenXml
.Spreadsheet.Row();
// Set values and formats for each cell for new row.
for (int ctr2 = 0; ctr2 < chartData.Columns.Count; ctr2++)
{
// Create a new cell.
DocumentFormat
.OpenXml
.Spreadsheet
.Cell newCell = new
DocumentFormat
.OpenXml
.Spreadsheet
.Cell();
// Create a new cell value for holding actual value of the cell.
DocumentFormat
.OpenXml
.Spreadsheet
.CellValue newCellValue = new
DocumentFormat
.OpenXml
.Spreadsheet
.CellValue();
// Set appropriate Style, Data Type and value for the cell.
switch (ctr2)
{
case 0:
newCell.StyleIndex = new
DocumentFormat
.OpenXml
.UInt32Value((uint)2);
newCellValue.Text =
chartData.Rows[ctr1][ctr2].ToString();
break;
case 1:
newCellValue.Text =
GetSharedStringIndex(
spreadsheetDocument
.WorkbookPart
.SharedStringTablePart,
chartData.Rows[ctr1][ctr2].ToString());
newCell.StyleIndex = new
DocumentFormat
.OpenXml
.UInt32Value((uint)2);
newCell.DataType =
DocumentFormat
.OpenXml
.Spreadsheet
.CellValues
.SharedString;
break;
case 2:
case 3:
newCellValue.Text =
chartData.Rows[ctr1][ctr2].ToString();
if (chartData.Rows[ctr1][ctr2] != DBNull.Value &&
chartData.Rows[ctr1][ctr2].ToString().Trim().Length > 0)
{
newCell.StyleIndex = new
DocumentFormat
.OpenXml
.UInt32Value((uint)3);
}
else
{
newCell.StyleIndex = new
DocumentFormat
.OpenXml
.UInt32Value((uint)1);
}
break;
}
// Append newly created cell value to the cell.
newCell.AppendChild(newCellValue);
// Append newly created cell to the Row.
newRecord.AppendChild(newCell);
}
// Append newly created row to the Excel sheet.
sheetData.AppendChild(newRecord);
}
spreadsheetDocument.Save();
}
}
}
}
}
}
catch (Exception)
{
}
finally
{
// Save the document.
mainDocumentPart.Document.Save();
}
}
}
private string GetSharedStringIndex(SharedStringTablePart sharedStringTablePart, string valueToSearch)
{
int counter = 0;
// Return index if item already exists.
foreach (DocumentFormat.OpenXml.Spreadsheet.SharedStringItem currentItem in sharedStringTablePart.SharedStringTable.Elements<DocumentFormat.OpenXml.Spreadsheet.SharedStringItem>())
{
if (currentItem.InnerText == valueToSearch)
{
return counter.ToString();
}
counter++;
}
// The text does not exist in the part. Create the SharedStringItem and return its index.
sharedStringTablePart.SharedStringTable.AppendChild(new DocumentFormat.OpenXml.Spreadsheet.SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(valueToSearch)));
sharedStringTablePart.SharedStringTable.Save();
return counter.ToString();
}