【问题标题】:remove non-ASCII characters (using Microsoft.Office.Interop.Excel)删除非 ASCII 字符(使用 Microsoft.Office.Interop.Excel)
【发布时间】:2017-06-29 15:10:45
【问题描述】:

我正在尝试从 excel / csv 文件中删除所有非 ascii 字符。在线阅读和搜索后,我发现一个帖子给了我代码xlWorksheet.UsedRange.Replace("[^\\u0000-\\u007F]" 以删除字符,但每次但字符仍然存在于文件中。

我也得到一个对话框说明

我们找不到可以替换的东西。单击选项以获取更多方法 搜索。

仅供参考:您尝试替换的数据可能位于受保护的 床单。 Excel 无法替换受保护工作表中的数据。

不确定如何继续。我一直在网上寻找和阅读,但到目前为止没有发现任何有用的东西。

感谢您的帮助。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Excel.Application xlApp = new Excel.Application();
            Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Users\username\Desktop\Error Records.csv");
            Excel.Worksheet xlWorksheet = xlWorkbook.Sheets[1];
            Excel.Range xlRange = xlWorksheet.UsedRange;

            int lastUsedRow = xlWorksheet.Cells.Find("*", System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious,
                false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Row;

            int lastUsedColumn = xlWorksheet.Cells.Find("*", System.Reflection.Missing.Value,
                System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                Excel.XlSearchOrder.xlByColumns, Excel.XlSearchDirection.xlPrevious,
                false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Column;

//            int lastColumnCount = lastUsedColumn;
//;
//            for (int i = 1; i <= lastUsedColumn; i++)
//            {
//                for (int j = 1; j <= lastUsedRow; j++)
//                {
//                    xlWorksheet.Cells[j, (lastColumnCount+1)] = "Testing data 134";
//                }
//            }

            xlWorksheet.Cells[1, (lastUsedColumn + 1)] = "Title";
            xlWorksheet.UsedRange.Replace("[^\\u0000-\\u007F]", string.Empty);

            xlWorkbook.Save();
            //cleanup
            GC.Collect();
            GC.WaitForPendingFinalizers();

            //rule of thumb for releasing com objects:
            //  never use two dots, all COM objects must be referenced and released individually
            //  ex: [somthing].[something].[something] is bad

            //release com objects to fully kill excel process from running in the background
            Marshal.ReleaseComObject(xlRange);
            Marshal.ReleaseComObject(xlWorksheet);

            //close and release
            xlWorkbook.SaveAs("C:\\Users\\username\\Desktop\\Errors_four.csv".Trim(), Excel.XlFileFormat.xlCSV);
            xlWorkbook.Close();
            Marshal.ReleaseComObject(xlWorkbook);

            //quit and release
            xlApp.Quit();
            Marshal.ReleaseComObject(xlApp);

        }
    }
}

【问题讨论】:

  • Excel 不支持正则表达式样式替换,因此您需要遍历每个单元格,将内容提取为字符串并对字符串进行替换并将其分配回单元格。

标签: c# .net excel


【解决方案1】:

对于每个范围内的每个单元格,您可以使用以下函数将当前单元格字符串值替换为清理后的ascii。我不知道 excel 互操作库原生的任何 ascii 转换函数。我很好奇,您是否可以提供任何示例来说明您尝试转换的内容?

还要记住,Excel 表中有函数,然后有值。您的问题不清楚您正在尝试使用哪个。您提到了 CSV,这让我觉得这些纯粹是 VALUES 操作。

public string ReturnCleanASCII(string s)
{
    StringBuilder sb = new StringBuilder(s.Length);
    foreach(char c in s.ToCharArray())
    {
       if((int)c > 127) // you probably don't want 127 either
          continue;
       if((int)c < 32)  // I bet you don't want control characters 
          continue;
       if(c == ',')
          continue;
       if(c == '"')
          continue;
       sb.Append(c);
    }
    return sb.ToString();
}

这是一个示例用法。请记住,您需要自己弄清楚如何索引单元格,此示例仅适用于单元格 1,1。此外,还有两个有用的提示:单元格是 1 索引的,如果您调用 Value2 而不是 Value,它可能会更快。

// get the value from a cell
string dirty = excelSheet.Cells[1, 1].Value.ToString(); // Value2 may be faster!

// convert to clean ascii
string clean = ReturnCleanASCII(dirty);

// set the cell value
excelSheet.Cells[1, 1].Value = clean;

【讨论】:

  • 我不确定如何将 xlWorkSheet 传递给字符串生成器。你能解释一下吗?
  • 感谢您的回复。关于我正在实施的内容的以下问题。 for (int i = 1; i
  • 看起来不错,但我没有通过调试器运行它或编译它。你有正确的想法。
猜你喜欢
  • 1970-01-01
  • 2012-01-24
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
相关资源
最近更新 更多