Skip to content

Commit

Permalink
Merge pull request #1095 from lahma/improve-write-speed
Browse files Browse the repository at this point in the history
Reduce string allocations when writing documents
  • Loading branch information
tonyqus committed Jul 22, 2023
2 parents ec9c232 + 29fea12 commit c1b836b
Show file tree
Hide file tree
Showing 28 changed files with 290 additions and 180 deletions.
2 changes: 1 addition & 1 deletion OpenXmlFormats/CustomXmlSchemaProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ internal void Write(StreamWriter sw, string nodeName)
XmlHelper.WriteAttribute(sw, "w:manifestLocation", this.manifestLocation);
XmlHelper.WriteAttribute(sw, "w:schemaLocation", this.schemaLocation);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

public CT_Schema()
Expand Down
2 changes: 1 addition & 1 deletion OpenXmlFormats/Drawing/WordprocessingDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ internal void Write(StreamWriter sw, string nodeName)
x.Write(sw, "inline");
}
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

List<CT_Anchor> anchorField;
Expand Down
26 changes: 19 additions & 7 deletions OpenXmlFormats/Spreadsheet/Document/CalcChainDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,27 @@ public void Save(Stream stream)
foreach (CT_CalcCell cc in calcChain.c)
{
sw.Write("<c");
sw.Write(" r=\""+cc.r+"\"");
if(cc.i>0)
sw.Write(" i=\"" + cc.i + "\"");
if(cc.s)
sw.Write(" s=\"" + (cc.s?1:0) + "\"");
sw.WriteAttribute("r", cc.r);

if (cc.i > 0)
{
sw.WriteAttribute("i", cc.i);
}

if (cc.s)
{
sw.WriteBooleanAttribute("s", cc.s);
}

if (cc.t)
sw.Write(" t=\"" + (cc.t?1:0) + "\"");
{
sw.WriteBooleanAttribute("t", cc.t);
}

if (cc.l)
sw.Write(" l=\"" + (cc.l?1:0) + "\"");
{
sw.WriteBooleanAttribute("l", cc.l);
}
sw.Write("/>");

}
Expand Down
7 changes: 5 additions & 2 deletions OpenXmlFormats/Spreadsheet/Sheet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2688,7 +2688,8 @@ public static CT_CellFormula Parse(XmlNode node, XmlNamespaceManager namespaceMa

internal void Write(StreamWriter sw, string nodeName)
{
sw.Write(string.Format("<{0}", nodeName));
sw.Write("<");
sw.Write(nodeName);
if (this.t != ST_CellFormulaType.normal)
XmlHelper.WriteAttribute(sw, "t", this.t.ToString());
XmlHelper.WriteAttribute(sw, "aca", this.aca, false);
Expand All @@ -2707,7 +2708,9 @@ internal void Write(StreamWriter sw, string nodeName)
{
sw.Write(">");
sw.Write(XmlHelper.EncodeXml(this.valueField).Replace("&quot;", "\""));
sw.Write(string.Format("</{0}>", nodeName));
sw.Write("</");
sw.Write(nodeName);
sw.Write(">");
}
else
{
Expand Down
7 changes: 4 additions & 3 deletions OpenXmlFormats/Spreadsheet/Sheet/CT_Cell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public static CT_Cell Parse(XmlNode node, XmlNamespaceManager namespaceManager)

internal void Write(StreamWriter sw, string nodeName)
{
sw.Write(string.Format("<{0}", nodeName));
sw.Write("<");
sw.Write(nodeName);

XmlHelper.WriteAttribute(sw, "r", this.r);
XmlHelper.WriteAttribute(sw, "s", this.s);
Expand All @@ -87,14 +88,14 @@ internal void Write(StreamWriter sw, string nodeName)
if (this.f != null)
this.f.Write(sw, "f");
if (!string.IsNullOrEmpty(this.v))
sw.Write(string.Format("<v>{0}</v>", XmlHelper.EncodeXml(this.v)));
sw.WriteElementAndContent("v", XmlHelper.EncodeXml(this.v));
else
sw.Write("<v/>");
if (this.@is != null)
this.@is.Write(sw, "is");
if (this.extLst != null)
this.extLst.Write(sw, "extLst");
sw.Write(string.Format("</{0}>", nodeName));
sw.WriteEndElement(nodeName);
}
}

Expand Down
5 changes: 3 additions & 2 deletions OpenXmlFormats/Spreadsheet/Sheet/CT_Row.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ public bool IsSetR()

internal void Write(StreamWriter sw, string nodeName)
{
sw.Write(string.Format("<{0}", nodeName));
sw.Write("<");
sw.Write(nodeName);
XmlHelper.WriteAttribute(sw, "r", this.r);
XmlHelper.WriteAttribute(sw, "spans", this.spans);
XmlHelper.WriteAttribute(sw, "s", this.s);
Expand All @@ -107,7 +108,7 @@ internal void Write(StreamWriter sw, string nodeName)
x.Write(sw, "c");
}
}
sw.Write(string.Format("</{0}>", nodeName));
sw.WriteEndElement(nodeName);
}


Expand Down
65 changes: 65 additions & 0 deletions OpenXmlFormats/StreamWriterExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System.IO;
using System.Runtime.CompilerServices;

namespace NPOI.OpenXmlFormats;

internal static class StreamWriterExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteAttribute(this StreamWriter sw, string name, string value)
{
sw.Write(" ");
sw.Write(name);
sw.Write("=\"");
sw.Write(value);
sw.Write("\"");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteAttribute(this StreamWriter sw, string name, int value)
{
sw.Write(" ");
sw.Write(name);
sw.Write("=\"");
sw.Write(value);
sw.Write("\"");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteBooleanAttribute(this StreamWriter sw, string name, bool value)
{
sw.Write(" ");
sw.Write(name);
sw.Write("=\"");
sw.Write(value ? 1 : 0);
sw.Write("\"");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteElementAndContent(this StreamWriter sw, string name, string value)
{
sw.Write("<");
sw.Write(name);
sw.Write(">");
sw.Write(value);
sw.Write("</");
sw.Write(name);
sw.Write(">");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteEndElement(this StreamWriter sw, string name)
{
sw.Write("</");
sw.Write(name);
sw.Write(">");
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void WriteEndW(this StreamWriter sw, string nodeName)
{
sw.Write("</w:");
sw.Write(nodeName);
sw.Write(">");
}
}
4 changes: 2 additions & 2 deletions OpenXmlFormats/Vml/WordprocessingDrawing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ internal void Write(StreamWriter sw, string nodeName)
XmlHelper.WriteAttribute(sw, "width", this.width);
NPOI.OpenXmlFormats.Util.XmlHelper.WriteAttribute(sw, "shadow", this.shadow);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlAttribute]
Expand Down Expand Up @@ -260,7 +260,7 @@ internal void Write(StreamWriter sw, string nodeName)
XmlHelper.WriteAttribute(sw, "anchorx", this.anchorx.ToString());
XmlHelper.WriteAttribute(sw, "anchory", this.anchory.ToString());
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlAttribute]
Expand Down
6 changes: 3 additions & 3 deletions OpenXmlFormats/Wordprocessing/BaseTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ internal void Write(StreamWriter sw, string nodeName)
sw.Write(string.Format("<w:{0}", nodeName));
XmlHelper.WriteAttribute(sw, "w:val", this.val);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}


Expand Down Expand Up @@ -484,7 +484,7 @@ internal void Write(StreamWriter sw, string nodeName)
sw.Write(string.Format("<w:{0}", nodeName));
XmlHelper.WriteAttribute(sw, "w:val", this.val);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
private string valField;
/// <summary>
Expand Down Expand Up @@ -616,7 +616,7 @@ internal void Write(StreamWriter sw, string nodeName)
sw.Write(string.Format("<w:{0}", nodeName));
XmlHelper.WriteAttribute(sw, "w:val", this.val);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

private string valField;
Expand Down
14 changes: 7 additions & 7 deletions OpenXmlFormats/Wordprocessing/CustomXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ internal void Write(StreamWriter sw, string nodeName)
else if (o is CT_CustomXmlRow)
((CT_CustomXmlRow)o).Write(sw, "customXml");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlElement(Order = 0)]
Expand Down Expand Up @@ -404,7 +404,7 @@ internal void Write(StreamWriter sw, string nodeName)
x.Write(sw, "attr");
}
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlElement(Order = 0)]
Expand Down Expand Up @@ -467,7 +467,7 @@ internal void Write(StreamWriter sw, string nodeName)
XmlHelper.WriteAttribute(sw, "w:name", this.name);
XmlHelper.WriteAttribute(sw, "w:val", this.val);
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlAttribute(Form = System.Xml.Schema.XmlSchemaForm.Qualified)]
Expand Down Expand Up @@ -1067,7 +1067,7 @@ internal void Write(StreamWriter sw, string nodeName)
else if (o is CT_OMathPara)
((CT_OMathPara)o).Write(sw, "oMathPara");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

}
Expand Down Expand Up @@ -1559,7 +1559,7 @@ internal void Write(StreamWriter sw, string nodeName)
else if (o is CT_Markup)
((CT_Markup)o).Write(sw, "customXmlMoveToRangeEnd");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

}
Expand Down Expand Up @@ -1932,7 +1932,7 @@ internal void Write(StreamWriter sw, string nodeName)
else if (o is CT_OMathPara)
((CT_OMathPara)o).Write(sw, "oMathPara");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlElement("oMath", typeof(CT_OMath), Namespace = "http://schemas.openxmlformats.org/officeDocument/2006/math", Order = 1)]
Expand Down Expand Up @@ -2363,7 +2363,7 @@ internal void Write(StreamWriter sw, string nodeName)
else if (o is CT_Markup)
((CT_Markup)o).Write(sw, "customXmlInsRangeEnd");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

[XmlElement(Order = 0)]
Expand Down
2 changes: 1 addition & 1 deletion OpenXmlFormats/Wordprocessing/Document.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ internal void Write(StreamWriter sw, string nodeName)
}
if (this.sectPr != null)
this.sectPr.Write(sw, "sectPr");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}

public CT_SectPr AddNewSectPr()
Expand Down
10 changes: 5 additions & 5 deletions OpenXmlFormats/Wordprocessing/FormField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ internal void Write(StreamWriter sw, string nodeName)
{
this.numberingChangeField.Write(sw, "numberingChange");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
}

Expand Down Expand Up @@ -416,7 +416,7 @@ internal void Write(StreamWriter sw, string nodeName)
(this.itemsField[i] as CT_FFTextInput).Write(sw, "textInput");
}

sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
private void AddNewObject(object obj, FFDataItemsType type)
{
Expand Down Expand Up @@ -642,7 +642,7 @@ internal void Write(StreamWriter sw, string nodeName)
else
(this.itemField as CT_HpsMeasure).Write(sw, "size");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
}

Expand Down Expand Up @@ -742,7 +742,7 @@ internal void Write(StreamWriter sw, string nodeName)
{
str.Write(sw, "listEntry");
}
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
}

Expand Down Expand Up @@ -1034,7 +1034,7 @@ internal void Write(StreamWriter sw, string nodeName)
if (this.maxLengthField != null)
this.maxLengthField.Write(sw, "maxLength");

sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}
}

Expand Down
2 changes: 1 addition & 1 deletion OpenXmlFormats/Wordprocessing/Frame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ internal void Write(StreamWriter sw, string nodeName)
XmlHelper.WriteAttribute(sw, "w:hRule", this.hRule.ToString());
XmlHelper.WriteAttribute(sw, "w:anchorLock", this.anchorLock.ToString());
sw.Write(">");
sw.Write(string.Format("</w:{0}>", nodeName));
sw.WriteEndW(nodeName);
}


Expand Down
Loading

0 comments on commit c1b836b

Please sign in to comment.