| using System; |
| using System.Collections.Generic; |
| using System.Globalization; |
| using System.Linq; |
| using System.Text; |
| using System.Text.RegularExpressions; |
| using OfficeOpenXml.FormulaParsing.ExpressionGraph; |
| using System.IO; |
| |
| namespace OfficeOpenXml.Utils |
| { |
| internal static class ConvertUtil |
| { |
| internal static bool IsNumeric(object candidate) |
| { |
| if (candidate == null) return false; |
| return (candidate.GetType().IsPrimitive || candidate is double || candidate is decimal || candidate is DateTime || candidate is TimeSpan || candidate is long); |
| } |
| |
| internal static bool IsNumericString(object candidate) |
| { |
| if (candidate != null) |
| { |
| return Regex.IsMatch(candidate.ToString(), @"^[\d]+(\,[\d])?"); |
| } |
| return false; |
| } |
| |
| /// <summary> |
| /// Convert an object value to a double |
| /// </summary> |
| /// <param name="v"></param> |
| /// <param name="ignoreBool"></param> |
| /// <returns></returns> |
| internal static double GetValueDouble(object v, bool ignoreBool = false) |
| { |
| double d; |
| try |
| { |
| if (ignoreBool && v is bool) |
| { |
| return 0; |
| } |
| if (IsNumeric(v)) |
| { |
| if (v is DateTime) |
| { |
| d = ((DateTime)v).ToOADate(); |
| } |
| else if (v is TimeSpan) |
| { |
| d = DateTime.FromOADate(0).Add((TimeSpan)v).ToOADate(); |
| } |
| else |
| { |
| d = Convert.ToDouble(v, CultureInfo.InvariantCulture); |
| } |
| } |
| else |
| { |
| d = 0; |
| } |
| } |
| |
| catch |
| { |
| d = 0; |
| } |
| return d; |
| } |
| /// <summary> |
| /// OOXML requires that "," , and & be escaped, but ' and " should *not* be escaped, nor should |
| /// any extended Unicode characters. This function only encodes the required characters. |
| /// System.Security.SecurityElement.Escape() escapes ' and " as ' and ", so it cannot |
| /// be used reliably. System.Web.HttpUtility.HtmlEncode overreaches as well and uses the numeric |
| /// escape equivalent. |
| /// </summary> |
| /// <param name="s"></param> |
| /// <returns></returns> |
| internal static string ExcelEscapeString(string s) |
| { |
| return s.Replace("&", "&").Replace("<", "<").Replace(">", ">"); |
| } |
| |
| /// <summary> |
| /// Return true if preserve space attribute is set. |
| /// </summary> |
| /// <param name="sw"></param> |
| /// <param name="t"></param> |
| /// <returns></returns> |
| internal static void ExcelEncodeString(StreamWriter sw, string t) |
| { |
| if (Regex.IsMatch(t, "(_x[0-9A-F]{4,4}_)")) |
| { |
| var match = Regex.Match(t, "(_x[0-9A-F]{4,4}_)"); |
| int indexAdd = 0; |
| while (match.Success) |
| { |
| t = t.Insert(match.Index + indexAdd, "_x005F"); |
| indexAdd += 6; |
| match = match.NextMatch(); |
| } |
| } |
| for (int i = 0; i < t.Length; i++) |
| { |
| if (t[i] <= 0x1f && t[i] != '\t' && t[i] != '\n' && t[i] != '\r') //Not Tab, CR or LF |
| { |
| sw.Write("_x00{0}_", (t[i] < 0xf ? "0" : "") + ((int)t[i]).ToString("X")); |
| } |
| else |
| { |
| sw.Write(t[i]); |
| } |
| } |
| |
| } |
| /// <summary> |
| /// Return true if preserve space attribute is set. |
| /// </summary> |
| /// <param name="sb"></param> |
| /// <param name="t"></param> |
| /// <returns></returns> |
| internal static void ExcelEncodeString(StringBuilder sb, string t, bool encodeTabCRLF=false) |
| { |
| if (Regex.IsMatch(t, "(_x[0-9A-F]{4,4}_)")) |
| { |
| var match = Regex.Match(t, "(_x[0-9A-F]{4,4}_)"); |
| int indexAdd = 0; |
| while (match.Success) |
| { |
| t = t.Insert(match.Index + indexAdd, "_x005F"); |
| indexAdd += 6; |
| match = match.NextMatch(); |
| } |
| } |
| for (int i = 0; i < t.Length; i++) |
| { |
| if (t[i] <= 0x1f && ((t[i] != '\t' && t[i] != '\n' && t[i] != '\r' && encodeTabCRLF == false) || encodeTabCRLF)) //Not Tab, CR or LF |
| { |
| sb.AppendFormat("_x00{0}_", (t[i] < 0xf ? "0" : "") + ((int)t[i]).ToString("X")); |
| } |
| else |
| { |
| sb.Append(t[i]); |
| } |
| } |
| |
| } |
| /// <summary> |
| /// Return true if preserve space attribute is set. |
| /// </summary> |
| /// <param name="sb"></param> |
| /// <param name="t"></param> |
| /// <returns></returns> |
| internal static string ExcelEncodeString(string t) |
| { |
| StringBuilder sb=new StringBuilder(); |
| t=t.Replace("\r\n", "\n"); //For some reason can't table name have cr in them. Replace with nl |
| ExcelEncodeString(sb, t, true); |
| return sb.ToString(); |
| } |
| internal static string ExcelDecodeString(string t) |
| { |
| var match = Regex.Match(t, "(_x005F|_x[0-9A-F]{4,4}_)"); |
| if (!match.Success) return t; |
| |
| var useNextValue = false; |
| var ret = new StringBuilder(); |
| var prevIndex = 0; |
| while (match.Success) |
| { |
| if (prevIndex < match.Index) ret.Append(t.Substring(prevIndex, match.Index - prevIndex)); |
| if (!useNextValue && match.Value == "_x005F") |
| { |
| useNextValue = true; |
| } |
| else |
| { |
| if (useNextValue) |
| { |
| ret.Append(match.Value); |
| useNextValue = false; |
| } |
| else |
| { |
| ret.Append((char)int.Parse(match.Value.Substring(2, 4), NumberStyles.AllowHexSpecifier)); |
| } |
| } |
| prevIndex = match.Index + match.Length; |
| match = match.NextMatch(); |
| } |
| ret.Append(t.Substring(prevIndex, t.Length - prevIndex)); |
| return ret.ToString(); |
| } |
| } |
| } |