public void X006_Xlsx_DeleteAdd_CoreExtendedProperties() { var docName = "Spreadsheet.xlsx"; var ba = File.ReadAllBytes(s_TestFileLocation + docName); using (MemoryStream ms = new MemoryStream()) { ms.Write(ba, 0, ba.Length); using (SpreadsheetDocument doc = SpreadsheetDocument.Open(ms, true)) { var corePart = doc.CoreFilePropertiesPart; var appPart = doc.ExtendedFilePropertiesPart; doc.DeletePart(corePart); doc.DeletePart(appPart); doc.AddCoreFilePropertiesPart(); doc.AddExtendedFilePropertiesPart(); doc.AddCustomFilePropertiesPart(); doc.AddDigitalSignatureOriginPart(); doc.AddExtendedPart("relType", "contentType/xml", ".xml"); var tnPart = doc.AddThumbnailPart(ThumbnailPartType.Jpeg); doc.DeletePart(tnPart); tnPart = doc.AddThumbnailPart("image/jpg"); OpenXmlValidator v = new OpenXmlValidator(FileFormatVersions.Office2013); var errs = v.Validate(doc); Assert.Equal(1, errs.Count()); } } }
// Adds child parts and generates content of the specified part. private void CreateParts(SpreadsheetDocument document) { var context = new SaveContext(); var workbookPart = document.WorkbookPart ?? document.AddWorkbookPart(); var worksheets = WorksheetsInternal; var partsToRemove = workbookPart.Parts.Where(s => worksheets.Deleted.Contains(s.RelationshipId)).ToList(); partsToRemove.ForEach(s => workbookPart.DeletePart(s.OpenXmlPart)); context.RelIdGenerator.AddValues(workbookPart.Parts.Select(p => p.RelationshipId).ToList(), RelType.Workbook); var extendedFilePropertiesPart = document.ExtendedFilePropertiesPart ?? document.AddNewPart<ExtendedFilePropertiesPart>( context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateExtendedFilePropertiesPartContent(extendedFilePropertiesPart); GenerateWorkbookPartContent(workbookPart, context); var sharedStringTablePart = workbookPart.SharedStringTablePart ?? workbookPart.AddNewPart<SharedStringTablePart>( context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateSharedStringTablePartContent(sharedStringTablePart, context); var workbookStylesPart = workbookPart.WorkbookStylesPart ?? workbookPart.AddNewPart<WorkbookStylesPart>( context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateWorkbookStylesPartContent(workbookStylesPart, context); foreach (var worksheet in WorksheetsInternal.Cast<XLWorksheet>().OrderBy(w => w.Position)) { //context.RelIdGenerator.Reset(RelType.); WorksheetPart worksheetPart; var wsRelId = worksheet.RelId; if (workbookPart.Parts.Any(p => p.RelationshipId == wsRelId)) { worksheetPart = (WorksheetPart)workbookPart.GetPartById(wsRelId); var wsPartsToRemove = worksheetPart.TableDefinitionParts.ToList(); wsPartsToRemove.ForEach(tdp => worksheetPart.DeletePart(tdp)); } else worksheetPart = workbookPart.AddNewPart<WorksheetPart>(wsRelId); context.RelIdGenerator.AddValues(worksheetPart.HyperlinkRelationships.Select(hr => hr.Id).ToList(), RelType.Workbook); context.RelIdGenerator.AddValues(worksheetPart.Parts.Select(p => p.RelationshipId).ToList(), RelType.Workbook); if (worksheetPart.DrawingsPart != null) context.RelIdGenerator.AddValues( worksheetPart.DrawingsPart.Parts.Select(p => p.RelationshipId).ToList(), RelType.Workbook); // delete comment related parts (todo: review) DeleteComments(worksheetPart, worksheet, context); if (worksheet.Internals.CellsCollection.GetCells(c => c.HasComment).Any()) { var worksheetCommentsPart = worksheetPart.AddNewPart<WorksheetCommentsPart>(context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateWorksheetCommentsPartContent(worksheetCommentsPart, worksheet); //VmlDrawingPart vmlDrawingPart = worksheetPart.AddNewPart<VmlDrawingPart>(worksheet.LegacyDrawingId); var vmlDrawingPart = worksheetPart.VmlDrawingParts.FirstOrDefault(); if (vmlDrawingPart == null) { if (XLHelper.IsNullOrWhiteSpace(worksheet.LegacyDrawingId)) { worksheet.LegacyDrawingId = context.RelIdGenerator.GetNext(RelType.Workbook); worksheet.LegacyDrawingIsNew = true; } vmlDrawingPart = worksheetPart.AddNewPart<VmlDrawingPart>(worksheet.LegacyDrawingId); } GenerateVmlDrawingPartContent(vmlDrawingPart, worksheet, context); } GenerateWorksheetPartContent(worksheetPart, worksheet, context); if (worksheet.PivotTables.Any()) { GeneratePivotTables(workbookPart, worksheetPart, worksheet, context); } //DrawingsPart drawingsPart = worksheetPart.AddNewPart<DrawingsPart>("rId1"); //GenerateDrawingsPartContent(drawingsPart, worksheet); //foreach (var chart in worksheet.Charts) //{ // ChartPart chartPart = drawingsPart.AddNewPart<ChartPart>("rId1"); // GenerateChartPartContent(chartPart, (XLChart)chart); //} } GenerateCalculationChainPartContent(workbookPart, context); if (workbookPart.ThemePart == null) { var themePart = workbookPart.AddNewPart<ThemePart>(context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateThemePartContent(themePart); } if (CustomProperties.Any()) { document.GetPartsOfType<CustomFilePropertiesPart>().ToList().ForEach(p => document.DeletePart(p)); var customFilePropertiesPart = document.AddNewPart<CustomFilePropertiesPart>(context.RelIdGenerator.GetNext(RelType.Workbook)); GenerateCustomFilePropertiesPartContent(customFilePropertiesPart); } SetPackageProperties(document); }
/// <summary> /// プロパティを書き込みます /// </summary> /// <param name="filePath"></param> /// <param name="propertiesTable"></param> /// <returns></returns> public bool WriteProperties(string filePath, string keyword, int filetype, bool bFileInfoUpdate, List <string> lstFinal, ref DateTime LastWriteTime, ref string error_reason) // 20171011 修正(ファイル書込み時のエラー理由を保存) // step2 iwasa { bool bRet = true; // 20171010 修正(try-catch追加(対象ファイルが存在しない場合に発生するエラー対応)) // (検索ボタン押下後、ファイルを移動/削除した場合など) try { System.IO.FileInfo fi = new System.IO.FileInfo(filePath); if (fi.Length == 0) { // ファイルサイズがゼロの場合プロパティが存在しないのでエラー // 20171228 追加(エラー理由保存) error_reason = ListForm.LIST_VIEW_NA; return(false); } // 最終版 } catch { // 対象ファイルが存在しない場合にここに来る // ファイルが存在しない場合のエラー error_reason = ListForm.LIST_VIEW_NA; return(false); } // ファイルのプロパティ領域を開く SpreadsheetDocument excel = null; WordprocessingDocument word = null; PresentationDocument ppt = null; CoreFilePropertiesPart coreFileProperties; // 20171010 修正(try-catch追加(開いているファイルを開こうとして発生するエラー対応)) try { switch (filetype) { case ListForm.EXTENSION_EXCEL: excel = SpreadsheetDocument.Open(filePath, true); coreFileProperties = excel.CoreFilePropertiesPart; break; case ListForm.EXTENSION_WORD: word = WordprocessingDocument.Open(filePath, true); coreFileProperties = word.CoreFilePropertiesPart; break; case ListForm.EXTENSION_POWERPOINT: ppt = PresentationDocument.Open(filePath, true); coreFileProperties = ppt.CoreFilePropertiesPart; break; default: // 異常なファイル // 20171228 追加(エラー理由保存) error_reason = ListForm.LIST_VIEW_NA; return(false); } } catch { // 開いているファイルを開いた場合にここに来る // ファイルが開かれている場合のエラー // または読み取り専用のファイル error_reason = ListForm.LIST_VIEW_NA; return(false); } LastWriteTime = new DateTime(); NameTable nt = new NameTable(); XmlNamespaceManager nsManager = new XmlNamespaceManager(nt); nsManager.AddNamespace(PropertiesKeyList.STR_TAG_CP, PropertiesSchemaList.CorePropertiesSchema); nsManager.AddNamespace(PropertiesKeyList.STR_TAG_DC, PropertiesSchemaList.DcPropertiesSchema); nsManager.AddNamespace(PropertiesKeyList.STR_TAG_DCTRMS, PropertiesSchemaList.DctermsPropertiesSchema); nsManager.AddNamespace(PropertiesKeyList.STR_TAG_DCMITYPE, PropertiesSchemaList.DcmitypePropertiesSchema); nsManager.AddNamespace(PropertiesKeyList.STR_TAG_XSI, PropertiesSchemaList.XsiPropertiesSchema); XmlDocument xdoc = new XmlDocument(); try { xdoc.Load(coreFileProperties.GetStream()); // 最終版のチェック string searchString = string.Format(PropertiesKeyList.STR_CORE_PROPERTIES + "{0}", PropertiesKeyList.STR_CONTENT_STATUS); // 書き込み先を検索 XmlNode xNode = xdoc.SelectSingleNode(searchString, nsManager); //if (xNode != null && xNode.InnerText == PropertiesKeyList.STR_FINAL_CONTENT) if (xNode != null && lstFinal.Contains(xNode.InnerText)) // step2 iwasa { // 最終版のファイルへの書き込みはできないのでエラーを返す // 20171228追加(エラーの理由を保存) error_reason = ListForm.LIST_VIEW_NA; return(false); } // 更新日時を読み込む // 書き込み先のキーワードを指定 searchString = string.Format(PropertiesKeyList.STR_CORE_PROPERTIES + "{0}", PropertiesKeyList.STR_MODIFIED); // 書き込み先を検索 xNode = xdoc.SelectSingleNode(searchString, nsManager); if (xNode != null) { LastWriteTime = DateTime.Parse(xNode.InnerText); } else { // なかったら今日の日付 LastWriteTime = DateTime.Now; } // キーワードの書込 // 書き込み先のキーワードを指定 searchString = string.Format(PropertiesKeyList.STR_CORE_PROPERTIES + "{0}", PropertiesKeyList.STR_KEYWORDS); // 書き込み先を検索 xNode = xdoc.SelectSingleNode(searchString, nsManager); if (xNode != null) { // 書き込む xNode.InnerText = keyword; } else { // keywordsタグが存在していないので作成する XmlNode node = xdoc.DocumentElement; // TSE kitada Comment. // .NETのバグ(?)により、"cp:keywords"を出力すると「:」より前をprefix扱いして勝手に削除してしまうため // Excelのフォーマットとして破損した形で出力されてしまう。 // "cp:"の部分は名前空間を指定することで勝手に付与されるので、qualifiedNameにはcp:をつけなくてよい。 XmlElement el = xdoc.CreateElement(PropertiesKeyList.STR_KEYWORDS, PropertiesSchemaList.CorePropertiesSchema); el.InnerText = keyword; node.AppendChild(el); } // カテゴリのリセット // 書き込み先のキーワードを指定 searchString = string.Format(PropertiesKeyList.STR_CORE_PROPERTIES + "{0}", PropertiesKeyList.STR_CATEGORY); // 書き込み先を検索 xNode = xdoc.SelectSingleNode(searchString, nsManager); if (xNode != null) { // 書き込む xNode.InnerText = ""; // 保存 //xdoc.Save(coreFileProperties.GetStream()); } // 20190705 TSE matsuo ファイルのプロパティ領域を再作成する if (excel != null) { excel.DeletePart(excel.CoreFilePropertiesPart); excel.AddCoreFilePropertiesPart(); coreFileProperties = excel.CoreFilePropertiesPart; } if (word != null) { word.DeletePart(word.CoreFilePropertiesPart); word.AddCoreFilePropertiesPart(); coreFileProperties = word.CoreFilePropertiesPart; } if (ppt != null) { ppt.DeletePart(ppt.CoreFilePropertiesPart); ppt.AddCoreFilePropertiesPart(); coreFileProperties = ppt.CoreFilePropertiesPart; } // 20180109 TSE kitada 保存は最後に一回だけ // 保存 xdoc.Save(coreFileProperties.GetStream()); } catch (Exception e) { bRet = false; // 20171011 追加 (読取専用、ファイ存在しない以外のエラー) error_reason = ListForm.LIST_VIEW_NA; } finally { // ファイルのプロパティ領域を閉じる if (excel != null) { excel.Close(); } if (word != null) { word.Close(); } if (ppt != null) { ppt.Close(); } } try { // 更新日は更新しない場合は元の更新日を上書きする if (!bFileInfoUpdate) { System.IO.File.SetLastWriteTime(filePath, LastWriteTime); } } catch (Exception e) { // 対象ファイルがロックされている場合はスルーする } return(bRet); }