zoukankan      html  css  js  c++  java
  • c# fastExcel库不支持特殊符号的修复

    说明:
    源码引用于:https://github.com/mrjono1/FastExcel
    由于,源码不支持在excel中添加特殊符号,故做了改动。改动如下:
    cell.cs文件的 internal StringBuilder ToXmlString(SharedStrings sharedStrings, int rowNumber)方法里添加了文本特殊符号的处理。

    cell.cs文件修改后如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Xml.Linq;
    
    namespace FastExcel
    {
        /// <summary>
        /// Contains the actual value
        /// </summary>
        public class Cell
        {
            /// <summary>
            /// Column Numnber (Starts at 1)
            /// </summary>
            public int ColumnNumber { get; set; }
    
            /// <summary>
            /// The value that is stored
            /// </summary>
            public object Value { get; set; }
    
            /// <summary>
            /// Defined name or the column letter(s) for column this cell is in
            /// </summary>
            public string ColumnName { get; }
            
            /// <summary>
            /// Raw underlying XElement of cell
            /// </summary>
            public XElement XElement { get; }
            
            /// <summary>
            /// List of defined names assigned to this cell
            /// *Does not include names of ranges this cell is within*
            /// </summary>
            public IReadOnlyList<string> CellNames { get; }
    
            /// <summary>
            /// First defined name assigned to cell or cell Letter + row number if no named defined.
            /// </summary>
            public string CellName
            {
                get
                {
                    if (CellNames.Any())
                        return CellNames.FirstOrDefault();
                    return ColumnName + RowNumber;
                }
            }
    
            /// <summary>
            /// Number of the row this cell is on
            /// </summary>
            public int RowNumber { get; }
    
            /// <summary>
            /// Create a new Cell
            /// </summary>
            /// <param name="columnNumber">Column number starting at 1</param>
            /// <param name="value">Cell Value</param>
            public Cell(int columnNumber, object value)
            {
                if (columnNumber <= 0)
                {
                    throw new Exception("Column numbers starting at 1");
                }
                ColumnNumber = columnNumber;
                ColumnName = GetExcelColumnName(columnNumber);
                RowNumber = 0;
                Value = value;
            }
    
            /// <summary>
            /// Create a new Cell
            /// </summary>
            /// <param name="cellElement">Cell</param>
            /// <param name="worksheet">The worksheet that this cell is on</param>
            public Cell(XElement cellElement, Worksheet worksheet)
            {
                bool isTextRow = (from a in cellElement.Attributes("t")
                                  where a.Value == "s"
                                  select a).Any();
                string columnName = (from a in cellElement.Attributes("r")
                                     select a.Value).FirstOrDefault();
    
                string columnLetter = Regex.Replace(columnName, @"d", "");
    
                RowNumber = Convert.ToInt32(Regex.Replace(columnName, @"[^d]", ""));
    
                ColumnName = worksheet.FastExcel.DefinedNames.FindColumnName(worksheet.Name, columnLetter) ?? columnLetter;
    
                CellNames = worksheet.FastExcel.DefinedNames.FindCellNames(worksheet.Name, columnLetter, RowNumber);
    
                ColumnNumber = GetExcelColumnNumber(columnName);
    
                XElement = cellElement;
    
                if (isTextRow)
                {
                    Value = worksheet.FastExcel.SharedStrings.GetString(cellElement.Value);
                }
                else
                {
                    // cellElement.Value will give a concatenated Value + reference/calculation
    
                    var node = cellElement.Elements().Where(x => x.Name.LocalName == "v").SingleOrDefault();
    
                    if (node != null)
                    {
                        Value = node.Value;
                    }
                    else
                    {
                        Value = cellElement.Value;
                    }
                    
                }
            }
    
            internal StringBuilder ToXmlString(SharedStrings sharedStrings, int rowNumber)
            {
                StringBuilder cell = new StringBuilder();
    
                if (Value != null)
                {
                    bool isString = false;
                    object value = Value;
    
                    if (Value is int)
                    {
                        isString = false;
                    }
                    else if (Value is double)
                    {
                        isString = false;
                    }
                    else if (Value is string)
                    {
                        isString = true;
                    }
    
                    if (isString)
                    {
                        var strValue = value.ToString();
                        //执行特殊符号检查
                        //由于xml存字符的时候,一些特殊字符会造成错误,因此,需要将特殊字符替代成xml识别的字符
                        //    "  to  &quot;
                        //    '  to  &apos;
                        //    <  to &lt;
                        //    >  to &gt;
                        //    &  to &amp; 
                        if (!string.IsNullOrEmpty(strValue))
                        {
                            strValue = strValue.Replace("&", "&amp;");
                            strValue = strValue.Replace("<", "&lt;");
                            strValue = strValue.Replace(">", "&gt;");
                            strValue = strValue.Replace(""", "&quot;");
                            strValue = strValue.Replace("'", "&apos;");
                        } 
                        value = sharedStrings.AddString(strValue);
                      
                    }
    
                    cell.AppendFormat("<c r="{0}{1}"{2}>", GetExcelColumnName(ColumnNumber), rowNumber, (isString ? " t="s"" : string.Empty));
                    cell.AppendFormat("<v>{0}</v>", value);
                    cell.Append("</c>");
                }
    
                return cell;
            }
    
            //http://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa
            /// <summary>
            /// Convert Column Number into Column Name - Character(s) eg 1-A, 2-B
            /// </summary>
            /// <param name="columnNumber">Column Number</param>
            /// <returns>Column Name - Character(s)</returns>
            public static string GetExcelColumnName(int columnNumber)
            {
                int dividend = columnNumber;
                string columnName = String.Empty;
                int modulo;
    
                while (dividend > 0)
                {
                    modulo = (dividend - 1) % 26;
                    columnName = string.Concat(Convert.ToChar(65 + modulo), columnName);
                    dividend = (int)((dividend - modulo) / 26);
                }
    
                return columnName;
            }
    
            //http://stackoverflow.com/questions/181596/how-to-convert-a-column-number-eg-127-into-an-excel-column-eg-aa
            /// <summary>
            /// Covert Column Name - Character(s) into a Column Number eg A-1, B-2, A1 - 1, B9 - 2
            /// </summary>
            /// <param name="columnName">Column Name - Character(s) optinally with the Row Number</param>
            /// <param name="includesRowNumber">Specify if the row number is included</param>
            /// <returns>Column Number</returns>
            public static int GetExcelColumnNumber(string columnName, bool includesRowNumber = true)
            {
                if (includesRowNumber)
                {
                    columnName = Regex.Replace(columnName, @"d", "");
                }
    
                int[] digits = new int[columnName.Length];
                for (int i = 0; i < columnName.Length; ++i)
                {
                    digits[i] = Convert.ToInt32(columnName[i]) - 64;
                }
                int mul = 1; int res = 0;
                for (int pos = digits.Length - 1; pos >= 0; --pos)
                {
                    res += digits[pos] * mul;
                    mul *= 26;
                }
                return res;
            }
    
            /// <summary>
            /// Merge the parameter cell into this cell
            /// </summary>
            /// <param name="cell">Cell to merge</param>
            public void Merge(Cell cell)
            {
                Value = cell.Value;
            }
        }
    }

    测试代码:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using FastExcel;
    
    namespace FastExcelTest
    {
        class Program
        {
            static void Main(string[] args)
            {
                SaveExcel();
                Console.WriteLine("ok");
                Console.Read();
            }
    
            private static void SaveExcel(string saveFileName = "testSave.xlsx")
            {
                FileInfo outputFile = new FileInfo(saveFileName);
                FileInfo epplusOutputFile = null;
                FileInfo templateFile = new FileInfo("Template.xlsx");
    
                if (outputFile.Exists)
                {
                    outputFile.Delete();
                    outputFile = new FileInfo(saveFileName);
                }
    
    
                using (FastExcel.FastExcel fastExcel = new FastExcel.FastExcel(templateFile, outputFile))
                {
    
                    //写入标题
                    Worksheet worksheet = new Worksheet();
    
                    worksheet.AddRow(new object[] { "标题1", "标题2", "属性1", "属性1" });
                    worksheet.AddRow(new object[] { "ssslkjl", "lkllkjffjfj", "在这里看节省了空间~!@#$%^&&*()_+{}|[]\、\;;',./<>?", "在这里看节省了空间~!@#$%^&&*()_+{}|[]\、\;;',./<>?" });
    
                    fastExcel.Write(worksheet, "sheet1");
                }
            }
        }
    }
  • 相关阅读:
    第4周课前测试考试题
    第3周课前测试考试题
    200行自定义异步非阻塞Web框架
    Web框架之Tornado
    redis总结
    Django之ModelForm组件
    Rabbitmq队列
    Git分布式版本控制系统
    Django REST framework
    python之路1
  • 原文地址:https://www.cnblogs.com/congqiandehoulai/p/12726356.html
Copyright © 2011-2022 走看看