Skip to content

Commit

Permalink
Merge pull request #15 from raptarych/custom-properties
Browse files Browse the repository at this point in the history
feature: get custom properties from xlsx
  • Loading branch information
aldobrynin authored May 4, 2023
2 parents 6fc5abe + b829a66 commit ce35c47
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

using SkbKontur.Excel.TemplateEngine.Exceptions;
using SkbKontur.Excel.TemplateEngine.FileGenerating;
using SkbKontur.Excel.TemplateEngine.FileGenerating.Primitives;
using SkbKontur.Excel.TemplateEngine.ObjectPrinting.ExcelDocumentPrimitives.Implementations;
using SkbKontur.Excel.TemplateEngine.ObjectPrinting.LazyParse;
using SkbKontur.Excel.TemplateEngine.ObjectPrinting.NavigationPrimitives.Implementations;
Expand Down Expand Up @@ -291,6 +292,51 @@ public void TestImportAfterCreate(string extension)
model.Type.Should().Be("Значение 2");
}

[TestCase("TemplateVersion", "1.9.text.$$%")]
[TestCase("another custom property", "another value")]
[TestCase("non-existent key", null)]
[TestCase(null, null)]
[TestCase("", null)]
public void TestGetCustomProperty(string key, string value)
{
var template = File.ReadAllBytes(GetFilePath("customProperties.xlsx"));
using (var templateModel = ExcelDocumentFactory.CreateFromTemplate(template, logger))
{
CheckCustomProperty(templateModel, key, value);
var printedDocument = templateModel.CloseAndGetDocumentBytes();
using (var printedDocumentModel = ExcelDocumentFactory.CreateFromTemplate(printedDocument, logger))
{
CheckCustomProperty(printedDocumentModel, key, value);
}
}
}

[TestCase("customProperties.xlsx")]
[TestCase("empty.xlsx", Description = "template file without custom properties")]
public void TestSetCustomProperty(string fileName)
{
var addedKey = "NewKey";
var addedValue = "CertainValue";
var templateBytes = File.ReadAllBytes(GetFilePath(fileName));
using (var template = ExcelDocumentFactory.CreateFromTemplate(templateBytes, logger))
{
CheckCustomProperty(template, addedKey, null);
template.SetCustomProperty(addedKey, addedValue);
CheckCustomProperty(template, addedKey, addedValue);
var printedDocumentBytes = template.CloseAndGetDocumentBytes();
using (var printedDocument = ExcelDocumentFactory.CreateFromTemplate(printedDocumentBytes, logger))
{
CheckCustomProperty(printedDocument, addedKey, addedValue);
}
}
}

private void CheckCustomProperty(IExcelDocument documentModel, string key, string value)
{
documentModel.TryGetCustomProperty(key, out var printedVersion).Should().Be(value != null);
printedVersion.Should().Be(value);
}

private (TModel model, Dictionary<string, string> mappingForErrors) Parse<TModel>(string templateFileName, string targetFileName)
where TModel : new()
{
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Linq;

using DocumentFormat.OpenXml.CustomProperties;
using DocumentFormat.OpenXml.Packaging;

using JetBrains.Annotations;

namespace SkbKontur.Excel.TemplateEngine.FileGenerating.Helpers;

public static class CustomFilePropertiesPartHelper
{
[CanBeNull]
public static CustomDocumentProperty GetProperty(this CustomFilePropertiesPart customFilePropertiesPart, string key)
{
return customFilePropertiesPart.Properties?.OfType<CustomDocumentProperty>()
.FirstOrDefault(i => i?.Name?.Value == key);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,10 @@ public interface IExcelDocument : IDisposable
void AddDescription([NotNull] string text);

void CopyVbaInfoFrom([NotNull] IExcelDocument excelDocument);

[ContractAnnotation("=> true, value:notnull; => false, value:null")]
bool TryGetCustomProperty([NotNull] string key, out string value);

void SetCustomProperty([NotNull] string key, string value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using System.Text;
using System.Xml;

using DocumentFormat.OpenXml.CustomProperties;
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.VariantTypes;

using JetBrains.Annotations;

Expand Down Expand Up @@ -168,6 +170,39 @@ public void RenameWorksheet(int index, [NotNull] string name)
spreadsheetDocument.WorkbookPart.Workbook.Sheets.Elements<Sheet>().ElementAt(index).Name = name;
}

public bool TryGetCustomProperty(string key, out string value)
{
ThrowIfSpreadsheetDisposed();
var property = spreadsheetDocument.CustomFilePropertiesPart?.GetProperty(key);
value = property?.InnerText;
return value != null;
}

public void SetCustomProperty(string key, string value)
{
// https://learn.microsoft.com/en-us/office/open-xml/how-to-set-a-custom-property-in-a-word-processing-document
const string customPropertyFormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}";
var customProps = spreadsheetDocument.CustomFilePropertiesPart
?? spreadsheetDocument.AddCustomFilePropertiesPart();
// ReSharper disable once ConstantNullCoalescingCondition
customProps.Properties ??= new Properties();

var existentProperty = customProps.GetProperty(key);
existentProperty?.Remove();
customProps.Properties.AppendChild(new CustomDocumentProperty
{
VTLPWSTR = new VTLPWSTR(value),
FormatId = customPropertyFormatId,
Name = key
});
var pid = 2;
foreach (var item in customProps.Properties.OfType<CustomDocumentProperty>())
{
item.PropertyId = pid++;
}
customProps.Properties.Save();
}

[NotNull]
public IExcelWorksheet AddWorksheet([NotNull] string worksheetName)
{
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.2",
"version": "1.3",
"assemblyVersion": {
"precision": "build"
},
Expand Down

0 comments on commit ce35c47

Please sign in to comment.