diff --git a/README.md b/README.md index c0dcd8b83..d425de730 100644 --- a/README.md +++ b/README.md @@ -15,11 +15,9 @@ This project is the .NET version of Apache POI project. With NPOI, you can read/ About Donation 关于捐款 ============ -Since Github sponsorship is not supported in China so far, it's hard to get donation from Github channel. I'm strictly limiting my contribution time on NPOI these 2 years although it looks to be still maintained well. +If you profits/benefits from NPOI and you believe it's useful, please [sponsor me via Github Sponsor](https://github.com/sponsors/tonyqus) or [donate this project](https://github.com/nissl-lab/npoi/discussions/923). Thank you! -If you profits/benefits from NPOI and you believe it's useful, please [donate this project](https://github.com/nissl-lab/npoi/discussions/923). Thank you! - -如果您从NPOI受益或实现盈利,请[给该项目捐款](https://github.com/nissl-lab/npoi/discussions/923),谢谢! +如果您从NPOI受益或实现盈利,请通过[Github Sponsor赞助我](https://github.com/sponsors/tonyqus)或[给该项目捐款](https://github.com/nissl-lab/npoi/discussions/923),谢谢! Telegram User Group @@ -54,7 +52,7 @@ e. Support not only export but also import f. Real successful cases all over the world -g. [huge amount of basic examples](https://github.com/nissl-lab/npoi-examples) +g. [huge amount of code examples for you to learn how to use NPOI](https://github.com/nissl-lab/npoi-examples) h. Works on both Windows and Linux diff --git a/build.ps1 b/build.ps1 index c0c0e6123..4634dc03e 100644 --- a/build.ps1 +++ b/build.ps1 @@ -20,9 +20,8 @@ $DotNetGlobalFile = "$PSScriptRoot\\global.json" $DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" $DotNetChannel = "STS" -$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 -$env:DOTNET_MULTILEVEL_LOOKUP = 0 +$env:DOTNET_NOLOGO = 1 ########################################################################### # EXECUTION @@ -61,6 +60,7 @@ else { ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } } $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" + $env:PATH = "$DotNetDirectory;$env:PATH" } Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)" diff --git a/build.sh b/build.sh index d4a7e51ec..fdff0c623 100755 --- a/build.sh +++ b/build.sh @@ -17,8 +17,7 @@ DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh" DOTNET_CHANNEL="STS" export DOTNET_CLI_TELEMETRY_OPTOUT=1 -export DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1 -export DOTNET_MULTILEVEL_LOOKUP=0 +export DOTNET_NOLOGO=1 ########################################################################### # EXECUTION @@ -54,11 +53,12 @@ else "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path fi export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" + export PATH="$DOTNET_DIRECTORY:$PATH" fi echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)" -if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "NUKE_ENTERPRISE_TOKEN" != "" ]]; then +if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true fi diff --git a/build/Build.cs b/build/Build.cs index f10232190..e6f4fbc1d 100644 --- a/build/Build.cs +++ b/build/Build.cs @@ -28,8 +28,6 @@ partial class Build : NukeBuild [Solution] Solution Solution; [GitRepository] readonly GitRepository GitRepository; - static AbsolutePath SourceDirectory => RootDirectory / "src"; - static AbsolutePath ArtifactsDirectory => RootDirectory / "publish"; string TagVersion => GitRepository.Tags.SingleOrDefault(x => x.StartsWith("v"))?[1..]; @@ -45,8 +43,6 @@ partial class Build : NukeBuild string VersionSuffix; - static bool IsRunningOnWindows => RuntimeInformation.IsOSPlatform(OSPlatform.Windows); - [Secret] [Parameter("GitHub API token")] readonly string GitHubToken; @@ -101,11 +97,11 @@ static void DeleteCompilationArtifacts() .Executes(() => { DotNetBuild(_ =>_ - .EnableNoRestore() + .SetNoRestore(SucceededTargets.Contains(Restore)) .SetConfiguration(Configuration) .SetDeterministic(IsServerBuild) .SetContinuousIntegrationBuild(IsServerBuild) - .SetVerbosity(DotNetVerbosity.Minimal) + .SetVerbosity(DotNetVerbosity.minimal) // obsolete missing XML documentation comment, XML comment on not valid language element, XML comment has badly formed XML, no matching tag in XML comment // need to use escaped separator in order for this to work .AddProperty("NoWarn", string.Join("%3B", new [] { 169, 612, 618, 1591, 1587, 1570, 1572, 1573, 1574 })) diff --git a/build/_build.csproj b/build/_build.csproj index 104cf021f..91a5396c8 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 CS0649;CS0169 .. @@ -11,7 +11,7 @@ - + diff --git a/main/NPOI.Core.csproj b/main/NPOI.Core.csproj index e8dff7bfa..e9dc91fad 100644 --- a/main/NPOI.Core.csproj +++ b/main/NPOI.Core.csproj @@ -18,10 +18,10 @@ - + - - + + diff --git a/main/SS/UserModel/IndexedColors.cs b/main/SS/UserModel/IndexedColors.cs index a8ee19924..932050c35 100644 --- a/main/SS/UserModel/IndexedColors.cs +++ b/main/SS/UserModel/IndexedColors.cs @@ -191,7 +191,7 @@ static IndexedColors() mappingName.Add("darkteal", IndexedColors.DarkTeal); mappingName.Add("seagreen", IndexedColors.SeaGreen); mappingName.Add("darkgreen", IndexedColors.DarkGreen); - mappingName.Add("olivergreen", IndexedColors.OliveGreen); + mappingName.Add("olivegreen", IndexedColors.OliveGreen); mappingName.Add("brown", IndexedColors.Brown); mappingName.Add("plum", IndexedColors.Plum); mappingName.Add("indigo", IndexedColors.Indigo); diff --git a/ooxml/XSSF/UserModel/XSSFRichTextString.cs b/ooxml/XSSF/UserModel/XSSFRichTextString.cs index fa999adce..c05add80b 100644 --- a/ooxml/XSSF/UserModel/XSSFRichTextString.cs +++ b/ooxml/XSSF/UserModel/XSSFRichTextString.cs @@ -22,6 +22,8 @@ limitations under the License. using System.Text; using System.Collections.Generic; using NPOI.XSSF.Model; +using System.Linq; + namespace NPOI.XSSF.UserModel { @@ -82,20 +84,18 @@ public XSSFRichTextString(String str) //PreserveSpaces(st.t); } - - public void SetStylesTableReference(StylesTable stylestable) { this.styles = stylestable; - if (st.sizeOfRArray() > 0) + if(st.sizeOfRArray() > 0) { - foreach (CT_RElt r in st.r) + foreach(CT_RElt r in st.r) { CT_RPrElt pr = r.rPr; - if (pr != null && pr.SizeOfRFontArray() > 0) + if(pr != null && pr.SizeOfRFontArray() > 0) { String fontName = pr.GetRFontArray(0).val; - if (fontName.StartsWith("#")) + if(fontName.StartsWith("#")) { int idx = int.Parse(fontName.Substring(1)); XSSFFont font = styles.GetFontAt(idx); @@ -106,6 +106,7 @@ public void SetStylesTableReference(StylesTable stylestable) } } } + /** * Create empty rich text string and Initialize it with empty string */ @@ -132,7 +133,7 @@ public XSSFRichTextString(CT_Rst st) public void ApplyFont(int startIndex, int endIndex, short fontIndex) { XSSFFont font; - if (styles == null) + if(styles == null) { //style table is not Set, remember fontIndex and Set the run properties later, //when SetStylesTableReference is called @@ -145,45 +146,61 @@ public void ApplyFont(int startIndex, int endIndex, short fontIndex) } ApplyFont(startIndex, endIndex, font); } - internal void ApplyFont(SortedDictionary formats, int startIndex, int endIndex, CT_RPrElt fmt) + + internal void ApplyFont(SortedDictionary formats, int startIndex, int endIndex, CT_RPrElt fmt) { - // delete format runs that fit between startIndex and endIndex // runs intersecting startIndex and endIndex remain - //int runStartIdx = 0; + int runStartIdx = 0; List toRemoveKeys=new List(); - for (SortedDictionary.KeyCollection.Enumerator it = formats.Keys.GetEnumerator(); it.MoveNext(); ) + for(SortedDictionary.KeyCollection.Enumerator it = formats.Keys.GetEnumerator(); it.MoveNext();) { - int runIdx = it.Current; - if (runIdx >= startIndex && runIdx < endIndex) + int runEndIdx = it.Current; + if(runStartIdx >= startIndex && runEndIdx < endIndex) { - toRemoveKeys.Add(runIdx); + toRemoveKeys.Add(runEndIdx); } + + runStartIdx = runEndIdx; } - foreach (int key in toRemoveKeys) + foreach(int key in toRemoveKeys) { formats.Remove(key); } - if (startIndex > 0 && !formats.ContainsKey(startIndex)) + + if(startIndex > 0 && !formats.ContainsKey(startIndex)) { // If there's a format that starts later in the string, make it start now - foreach (KeyValuePair entry in formats) + foreach(KeyValuePair entry in formats) { - if (entry.Key > startIndex) + if(entry.Key > startIndex) { formats[startIndex] = entry.Value; break; } } } + formats[endIndex] = fmt; // assure that the range [startIndex, endIndex] consists if a single run // there can be two or three runs depending whether startIndex or endIndex // intersected existing format runs - //SortedMap sub = formats.subMap(startIndex, endIndex); - //while(sub.size() > 1) sub.remove(sub.lastKey()); + var sub = new List(); + for(int idx = startIndex; idx 1) + { + var last = sub.Last(); + sub.Remove(last); + formats.Remove(last); + } } + /** * Applies a font to the specified characters of a string. * @@ -193,14 +210,14 @@ internal void ApplyFont(SortedDictionary formats, int startIndex */ public void ApplyFont(int startIndex, int endIndex, IFont font) { - if (startIndex > endIndex) + if(startIndex > endIndex) throw new ArgumentException("Start index must be less than end index, but had " + startIndex + " and " + endIndex); - if (startIndex < 0 || endIndex > Length) + if(startIndex < 0 || endIndex > Length) throw new ArgumentException("Start and end index not in range, but had " + startIndex + " and " + endIndex); - if (startIndex == endIndex) + if(startIndex == endIndex) return; - if (st.sizeOfRArray() == 0 && st.IsSetT()) + if(st.sizeOfRArray() == 0 && st.IsSetT()) { //convert string into a text Run: string st.AddNewR().t = (st.t); @@ -217,15 +234,13 @@ public void ApplyFont(int startIndex, int endIndex, IFont font) CT_Rst newSt = BuildCTRst(text, formats); st.Set(newSt); - - - } + internal SortedDictionary GetFormatMap(CT_Rst entry) { int length = 0; SortedDictionary formats = new SortedDictionary(); - foreach (CT_RElt r in entry.r) + foreach(CT_RElt r in entry.r) { String txt = r.t; CT_RPrElt fmt = r.rPr; @@ -235,6 +250,7 @@ internal SortedDictionary GetFormatMap(CT_Rst entry) } return formats; } + /** * Sets the font of the entire string. * @param font The font to use. @@ -253,7 +269,7 @@ public void ApplyFont(IFont font) public void ApplyFont(short fontIndex) { XSSFFont font; - if (styles == null) + if(styles == null) { font = new XSSFFont(); font.FontName = ("#" + fontIndex); @@ -274,7 +290,7 @@ public void ApplyFont(short fontIndex) */ public void Append(String text, XSSFFont font) { - if (st.sizeOfRArray() == 0 && st.IsSetT()) + if(st.sizeOfRArray() == 0 && st.IsSetT()) { //convert string into a text Run: string CT_RElt lt = st.AddNewR(); @@ -285,12 +301,12 @@ public void Append(String text, XSSFFont font) CT_RElt lt2 = st.AddNewR(); lt2.t= (text); //PreserveSpaces(lt2.t); - - if (font != null) + + if(font != null) { CT_RPrElt pr = lt2.AddNewRPr(); SetRunAttributes(font.GetCTFont(), pr); - } + } } /** @@ -308,51 +324,65 @@ public void Append(String text) */ private void SetRunAttributes(CT_Font ctFont, CT_RPrElt pr) { - if (ctFont.SizeOfBArray() > 0) pr.AddNewB().val = (ctFont.GetBArray(0).val); - if (ctFont.sizeOfUArray() > 0) pr.AddNewU().val =(ctFont.GetUArray(0).val); - if (ctFont.sizeOfIArray() > 0) pr.AddNewI().val =(ctFont.GetIArray(0).val); - if (ctFont.sizeOfColorArray() > 0) + if(ctFont.SizeOfBArray() > 0) + pr.AddNewB().val = (ctFont.GetBArray(0).val); + if(ctFont.sizeOfUArray() > 0) + pr.AddNewU().val =(ctFont.GetUArray(0).val); + if(ctFont.sizeOfIArray() > 0) + pr.AddNewI().val =(ctFont.GetIArray(0).val); + if(ctFont.sizeOfColorArray() > 0) { CT_Color c1 = ctFont.GetColorArray(0); CT_Color c2 = pr.AddNewColor(); - if (c1.IsSetAuto()) + if(c1.IsSetAuto()) { c2.auto = (c1.auto); c2.autoSpecified = true; } - if (c1.IsSetIndexed()) + if(c1.IsSetIndexed()) { c2.indexed = (c1.indexed); c2.indexedSpecified = true; } - if (c1.IsSetRgb()) + if(c1.IsSetRgb()) { c2.SetRgb(c1.rgb); c2.rgbSpecified = true; } - if (c1.IsSetTheme()) + if(c1.IsSetTheme()) { c2.theme = (c1.theme); c2.themeSpecified = true; } - if (c1.IsSetTint()) + if(c1.IsSetTint()) { c2.tint = (c1.tint); c2.tintSpecified = true; } } - if (ctFont.sizeOfSzArray() > 0) pr.AddNewSz().val = (ctFont.GetSzArray(0).val); - if (ctFont.sizeOfNameArray() > 0) pr.AddNewRFont().val = (ctFont.name.val); - if (ctFont.sizeOfFamilyArray() > 0) pr.AddNewFamily().val =(ctFont.GetFamilyArray(0).val); - if (ctFont.sizeOfSchemeArray() > 0) pr.AddNewScheme().val = (ctFont.GetSchemeArray(0).val); - if (ctFont.sizeOfCharsetArray() > 0) pr.AddNewCharset().val = (ctFont.GetCharsetArray(0).val); - if (ctFont.sizeOfCondenseArray() > 0) pr.AddNewCondense().val = (ctFont.GetCondenseArray(0).val); - if (ctFont.sizeOfExtendArray() > 0) pr.AddNewExtend().val = (ctFont.GetExtendArray(0).val); - if (ctFont.sizeOfVertAlignArray() > 0) pr.AddNewVertAlign().val = (ctFont.GetVertAlignArray(0).val); - if (ctFont.sizeOfOutlineArray() > 0) pr.AddNewOutline().val =(ctFont.GetOutlineArray(0).val); - if (ctFont.sizeOfShadowArray() > 0) pr.AddNewShadow().val =(ctFont.GetShadowArray(0).val); - if (ctFont.sizeOfStrikeArray() > 0) pr.AddNewStrike().val = (ctFont.GetStrikeArray(0).val); + if(ctFont.sizeOfSzArray() > 0) + pr.AddNewSz().val = (ctFont.GetSzArray(0).val); + if(ctFont.sizeOfNameArray() > 0) + pr.AddNewRFont().val = (ctFont.name.val); + if(ctFont.sizeOfFamilyArray() > 0) + pr.AddNewFamily().val =(ctFont.GetFamilyArray(0).val); + if(ctFont.sizeOfSchemeArray() > 0) + pr.AddNewScheme().val = (ctFont.GetSchemeArray(0).val); + if(ctFont.sizeOfCharsetArray() > 0) + pr.AddNewCharset().val = (ctFont.GetCharsetArray(0).val); + if(ctFont.sizeOfCondenseArray() > 0) + pr.AddNewCondense().val = (ctFont.GetCondenseArray(0).val); + if(ctFont.sizeOfExtendArray() > 0) + pr.AddNewExtend().val = (ctFont.GetExtendArray(0).val); + if(ctFont.sizeOfVertAlignArray() > 0) + pr.AddNewVertAlign().val = (ctFont.GetVertAlignArray(0).val); + if(ctFont.sizeOfOutlineArray() > 0) + pr.AddNewOutline().val =(ctFont.GetOutlineArray(0).val); + if(ctFont.sizeOfShadowArray() > 0) + pr.AddNewShadow().val =(ctFont.GetShadowArray(0).val); + if(ctFont.sizeOfStrikeArray() > 0) + pr.AddNewStrike().val = (ctFont.GetStrikeArray(0).val); } /** @@ -362,13 +392,14 @@ private void SetRunAttributes(CT_Font ctFont, CT_RPrElt pr) public bool HasFormatting() { List rs = st.r; - if (rs == null || rs.Count == 0) + if(rs == null || rs.Count == 0) { return false; } - foreach (CT_RElt r in rs) + foreach(CT_RElt r in rs) { - if (r.isSetRPr()) return true; + if(r.isSetRPr()) + return true; } return false; } @@ -391,13 +422,15 @@ public void ClearFormatting() */ public int GetIndexOfFormattingRun(int index) { - if (st.sizeOfRArray() == 0) return 0; + if(st.sizeOfRArray() == 0) + return 0; int pos = 0; - for (int i = 0; i < st.sizeOfRArray(); i++) + for(int i = 0; i < st.sizeOfRArray(); i++) { CT_RElt r = st.GetRArray(i); - if (i == index) return pos; + if(i == index) + return pos; pos += r.t.Length; } @@ -412,7 +445,7 @@ public int GetIndexOfFormattingRun(int index) */ public int GetLengthOfFormattingRun(int index) { - if (st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) + if(st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) { return -1; } @@ -425,19 +458,19 @@ public String String { get { - if (st.sizeOfRArray() == 0) + if(st.sizeOfRArray() == 0) { return UtfDecode(st.t); } StringBuilder buf = new StringBuilder(); - foreach (CT_RElt r in st.r) + foreach(CT_RElt r in st.r) { buf.Append(r.t); } return UtfDecode(buf.ToString()); } - set + set { ClearFormatting(); st.t = value; @@ -483,10 +516,11 @@ public int NumFormattingRuns */ public IFont GetFontOfFormattingRun(int index) { - if (st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) return null; + if(st.sizeOfRArray() == 0 || index >= st.sizeOfRArray()) + return null; CT_RElt r = st.GetRArray(index); - if (r.rPr != null) + if(r.rPr != null) { XSSFFont fnt = new XSSFFont(ToCTFont(r.rPr)); fnt.SetThemesTable(GetThemesTable()); @@ -507,14 +541,14 @@ public XSSFFont GetFontAtIndex(int index) { ThemesTable themes = GetThemesTable(); int pos = 0; - if (st.r == null) + if(st.r == null) { return null; } - foreach (CT_RElt r in st.r) + foreach(CT_RElt r in st.r) { int length = r.t.Length; - if (index >= pos && index < pos + length) + if(index >= pos && index < pos + length) { XSSFFont fnt = new XSSFFont(ToCTFont(r.rPr)); fnt.SetThemesTable(themes); @@ -535,7 +569,6 @@ public CT_Rst GetCTRst() return st; } - /** * * CTRPrElt --> CTFont adapter @@ -544,55 +577,69 @@ protected static CT_Font ToCTFont(CT_RPrElt pr) { CT_Font ctFont = new CT_Font(); // Bug 58315: there are files where there is no pr-entry for a RichTextString - if (pr == null) + if(pr == null) { return ctFont; } - if (pr.SizeOfBArray() > 0) ctFont.AddNewB().val = (pr.GetBArray(0).val); - if (pr.SizeOfUArray() > 0) ctFont.AddNewU().val = (pr.GetUArray(0).val); - if (pr.SizeOfIArray() > 0) ctFont.AddNewI().val = (pr.GetIArray(0).val); - if (pr.SizeOfColorArray() > 0) + if(pr.SizeOfBArray() > 0) + ctFont.AddNewB().val = (pr.GetBArray(0).val); + if(pr.SizeOfUArray() > 0) + ctFont.AddNewU().val = (pr.GetUArray(0).val); + if(pr.SizeOfIArray() > 0) + ctFont.AddNewI().val = (pr.GetIArray(0).val); + if(pr.SizeOfColorArray() > 0) { CT_Color c1 = pr.GetColorArray(0); CT_Color c2 = ctFont.AddNewColor(); - if (c1.IsSetAuto()) + if(c1.IsSetAuto()) { c2.auto = (c1.auto); c2.autoSpecified = true; } - if (c1.IsSetIndexed()) + if(c1.IsSetIndexed()) { c2.indexed = (c1.indexed); c2.indexedSpecified = true; } - if (c1.IsSetRgb()) + if(c1.IsSetRgb()) { c2.SetRgb(c1.GetRgb()); c2.rgbSpecified = true; } - if (c1.IsSetTheme()) + if(c1.IsSetTheme()) { c2.theme = (c1.theme); c2.themeSpecified = true; } - if (c1.IsSetTint()) + if(c1.IsSetTint()) { c2.tint = (c1.tint); c2.tintSpecified = true; } } - - if (pr.SizeOfSzArray() > 0) ctFont.AddNewSz().val = (pr.GetSzArray(0).val); - if (pr.SizeOfRFontArray() > 0) ctFont.AddNewName().val = (pr.GetRFontArray(0).val); - if (pr.SizeOfFamilyArray() > 0) ctFont.AddNewFamily().val = (pr.GetFamilyArray(0).val); - if (pr.sizeOfSchemeArray() > 0) ctFont.AddNewScheme().val = (pr.GetSchemeArray(0).val); - if (pr.sizeOfCharsetArray() > 0) ctFont.AddNewCharset().val = (pr.GetCharsetArray(0).val); - if (pr.sizeOfCondenseArray() > 0) ctFont.AddNewCondense().val = (pr.GetCondenseArray(0).val); - if (pr.sizeOfExtendArray() > 0) ctFont.AddNewExtend().val = (pr.GetExtendArray(0).val); - if (pr.sizeOfVertAlignArray() > 0) ctFont.AddNewVertAlign().val = (pr.GetVertAlignArray(0).val); - if (pr.sizeOfOutlineArray() > 0) ctFont.AddNewOutline().val = (pr.GetOutlineArray(0).val); - if (pr.sizeOfShadowArray() > 0) ctFont.AddNewShadow().val = (pr.GetShadowArray(0).val); - if (pr.sizeOfStrikeArray() > 0) ctFont.AddNewStrike().val = (pr.GetStrikeArray(0).val); + + if(pr.SizeOfSzArray() > 0) + ctFont.AddNewSz().val = (pr.GetSzArray(0).val); + if(pr.SizeOfRFontArray() > 0) + ctFont.AddNewName().val = (pr.GetRFontArray(0).val); + if(pr.SizeOfFamilyArray() > 0) + ctFont.AddNewFamily().val = (pr.GetFamilyArray(0).val); + if(pr.sizeOfSchemeArray() > 0) + ctFont.AddNewScheme().val = (pr.GetSchemeArray(0).val); + if(pr.sizeOfCharsetArray() > 0) + ctFont.AddNewCharset().val = (pr.GetCharsetArray(0).val); + if(pr.sizeOfCondenseArray() > 0) + ctFont.AddNewCondense().val = (pr.GetCondenseArray(0).val); + if(pr.sizeOfExtendArray() > 0) + ctFont.AddNewExtend().val = (pr.GetExtendArray(0).val); + if(pr.sizeOfVertAlignArray() > 0) + ctFont.AddNewVertAlign().val = (pr.GetVertAlignArray(0).val); + if(pr.sizeOfOutlineArray() > 0) + ctFont.AddNewOutline().val = (pr.GetOutlineArray(0).val); + if(pr.sizeOfShadowArray() > 0) + ctFont.AddNewShadow().val = (pr.GetShadowArray(0).val); + if(pr.sizeOfStrikeArray() > 0) + ctFont.AddNewStrike().val = (pr.GetStrikeArray(0).val); return ctFont; } @@ -605,11 +652,11 @@ protected static CT_Font ToCTFont(CT_RPrElt pr) protected static void PreserveSpaces(string xs) { String text = xs; - if (text != null && text.Length > 0) + if(text != null && text.Length > 0) { char firstChar = text[0]; char lastChar = text[text.Length - 1]; - if (Char.IsWhiteSpace(firstChar) || Char.IsWhiteSpace(lastChar)) + if(Char.IsWhiteSpace(firstChar) || Char.IsWhiteSpace(lastChar)) { //XmlCursor c = xs.newCursor(); //c.ToNextToken(); @@ -634,29 +681,30 @@ protected static void PreserveSpaces(string xs) */ static String UtfDecode(String value) { - if (value == null) return null; + if(value == null) + return null; StringBuilder buf = new StringBuilder(); MatchCollection mc = utfPtrn.Matches(value); int idx = 0; - for (int i = 0; i < mc.Count; i++) + for(int i = 0; i < mc.Count; i++) { int pos = mc[i].Index; - if (pos > idx) + if(pos > idx) { buf.Append(value.Substring(idx, pos - idx)); } String code = mc[i].Groups[1].Value; int icode = Int32.Parse(code, System.Globalization.NumberStyles.AllowHexSpecifier); - buf.Append((char)icode); + buf.Append((char) icode); idx = mc[i].Index + mc[i].Length; } // small optimization: don't go via StringBuilder if not necessary, // the encodings are very rare, so we should almost always go via this shortcut. - if (idx == 0) + if(idx == 0) { return value; } @@ -668,9 +716,9 @@ static String UtfDecode(String value) public int GetLastKey(SortedDictionary.KeyCollection keys) { int i=0; - foreach (int key in keys) + foreach(int key in keys) { - if (i == keys.Count - 1) + if(i == keys.Count - 1) return key; i++; } @@ -679,14 +727,14 @@ public int GetLastKey(SortedDictionary.KeyCollection keys) CT_Rst BuildCTRst(String text, SortedDictionary formats) { - if (text.Length != GetLastKey(formats.Keys)) + if(text.Length != GetLastKey(formats.Keys)) { throw new ArgumentException("Text length was " + text.Length + " but the last format index was " + GetLastKey(formats.Keys)); } CT_Rst st = new CT_Rst(); int runStartIdx = 0; - foreach (KeyValuePair kv in formats) + foreach(KeyValuePair kv in formats) { int runEndIdx = kv.Key; CT_RElt run = st.AddNewR(); @@ -694,7 +742,7 @@ CT_Rst BuildCTRst(String text, SortedDictionary formats) run.t = (fragment); //PreserveSpaces(run.t); CT_RPrElt fmt = kv.Value; - if (fmt != null) + if(fmt != null) { run.rPr = fmt; } @@ -705,9 +753,9 @@ CT_Rst BuildCTRst(String text, SortedDictionary formats) private ThemesTable GetThemesTable() { - if (styles == null) return null; + if(styles == null) + return null; return styles.GetTheme(); } } } - diff --git a/solution/NPOI.Core.Test.sln b/solution/NPOI.Core.Test.sln index 9328d5a3b..188036c0a 100644 --- a/solution/NPOI.Core.Test.sln +++ b/solution/NPOI.Core.Test.sln @@ -63,9 +63,7 @@ Global {DA2CA3BD-1CAC-470C-9FA2-611A5768A76A}.Release|Any CPU.ActiveCfg = Release|Any CPU {DA2CA3BD-1CAC-470C-9FA2-611A5768A76A}.Release|Any CPU.Build.0 = Release|Any CPU {94B18BCF-84E8-401F-BAAB-0496AA136628}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {94B18BCF-84E8-401F-BAAB-0496AA136628}.Debug|Any CPU.Build.0 = Debug|Any CPU {94B18BCF-84E8-401F-BAAB-0496AA136628}.Release|Any CPU.ActiveCfg = Release|Any CPU - {94B18BCF-84E8-401F-BAAB-0496AA136628}.Release|Any CPU.Build.0 = Release|Any CPU {3DA1149D-46F8-4181-9976-E002BF2BFB76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {3DA1149D-46F8-4181-9976-E002BF2BFB76}.Debug|Any CPU.Build.0 = Debug|Any CPU {3DA1149D-46F8-4181-9976-E002BF2BFB76}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/testcases/ooxml/XSSF/UserModel/TestXSSFRichTextString.cs b/testcases/ooxml/XSSF/UserModel/TestXSSFRichTextString.cs index 90d3818e4..8b9a46c5b 100644 --- a/testcases/ooxml/XSSF/UserModel/TestXSSFRichTextString.cs +++ b/testcases/ooxml/XSSF/UserModel/TestXSSFRichTextString.cs @@ -77,7 +77,7 @@ public void TestApplyFont() Assert.AreEqual(false, rt.HasFormatting()); XSSFFont font1 = new XSSFFont(); - font1.IsBold = (true); + font1.IsBold = true; rt.ApplyFont(2, 5, font1); Assert.AreEqual(true, rt.HasFormatting()); @@ -595,5 +595,30 @@ public void Test59008Font() //Assert.AreEqual("", rts.GetFontAtIndex(s3 - 1).ToString()); Assert.AreEqual("", rts.GetFontAtIndex(s3 - 1).ToString()); } + + [Test] + public void TestMultipleFonts() + { + var f1 = new XSSFFont(); + f1.FontName = "Arial"; + f1.FontHeight = 18 * 20; + f1.IsBold = false; + f1.Color = IndexedColors.Red.Index; + + var f2 = new XSSFFont(); + f2.FontName = "Arial"; + f2.FontHeight = 18 * 20; + f2.IsBold = true; + f2.Color = IndexedColors.Blue.Index; + + XSSFRichTextString s = new XSSFRichTextString("0123"); + s.ApplyFont(0, 2, f1); + s.ApplyFont(2, 4, f2); + + Assert.AreEqual(s.GetFontAtIndex(0).Color, IndexedColors.Red.Index); + Assert.AreEqual(s.GetFontAtIndex(1).Color, IndexedColors.Red.Index); + Assert.AreEqual(s.GetFontAtIndex(2).Color, IndexedColors.Blue.Index); + Assert.AreEqual(s.GetFontAtIndex(3).Color, IndexedColors.Blue.Index); + } } } \ No newline at end of file