问题描述:需要将一个csv格式的表格文件转换成我想要的表格内容形式。(前四行的每个竖列转换成每行得横列,然后第五行得横列于前三行结合拼接成一行,类似这种得样式)
待转格式 转换后
最开始写的时候用的是Microsoft.Office.Interop.Excel库,挨个单元格读excel然后再挨个单元格写入文件,谁用谁知道,刚开始没用多大的文件就几兆大概转换完的时间要个半小时,但是我们这边需要转的竟然大多都是上百兆得文件,转换后粗滤算下需要两千多万行,excel文件最多也就只能有一百多万行。
一次要转换几十个文件照这个速度要一周,得!重写。
由于之前也写过一个读千万行的csv文件,与之不同的是,只要读,不要文件处理,每读五百行转换成json传给客户,用的StreamReader,由于我的excel要做文件处理,StreamReader是按行读,效率快但是想直接操作单元格数据还要自己处理,我就抱着试试心态重写了一份。利用StreamReader读,StreamWriter写。
StringBuilder sbData = new StringBuilder();
StringBuilder nsbData = new StringBuilder();
string sbHeader = sb.ToString();
//sbData = sb;
System.IO.FileStream fs = null;
StreamWriter sw = null;
try
{
sbData.Append(sbHeader);
for (int k = 1; k <= (wsRows - paraLine); k++)//(wsRows - paraLine)
{
lineTxt = reader.ReadLine();
nLineCount++;
string[] split = lineTxt.Split(',');
for (int i = colTemp; i < wsColumns; i++)
{
if (split[i].ToString() == "")
{
breakCount = breakCount +( wsColumns - split.Length-1);
break;
}
if (float.Parse(split[i].ToString()) <= float.Parse(d[i].ToString()) && (float.Parse(split[i].ToString()) >= float.Parse(c[i].ToString())))
{
testResult = "PASS";
}
else
{
testResult = "FAIL";
}
sbData.Append("***\t");
sbData.Append("*****\t");
sbData.Append("******D3\t");
sbData.Append(barName + "\t");
sbData.Append(barCode + "\t");
sbData.Append(k + "\t");
sbData.Append("\t");
sbData.Append("\t");
sbData.Append(processBatch + "\t");
sbData.Append(productLine + "\t");
sbData.Append(testEquip + "\t");
sbData.Append(testTime + "\t");
sbData.Append(testType + "\t");
sbData.Append(testProcess + "\t");
sbData.Append(a[i].ToString() + "\t");
sbData.Append(testCondition + "\t");
sbData.Append(c[i].ToString() + "\t");
sbData.Append(d[i].ToString() + "\t");
sbData.Append(b[i].ToString() + "\t");
sbData.Append(split[i].ToString() + "\t");
sbData.Append("\t");
sbData.Append(testResult + "\t");
sbData.Append("\t");
sbData.Append(Environment.NewLine);
dataLineCount++;
backgroundWorker1.ReportProgress(k * 100 / (wsRows - paraLine), "正在转换文件:" + "..\\" + fileName);//(dataLineCount * 100) / ((wsRows - paraLine) * (wsColumns - 6)-breakCount)
if (dataLineCount % 800000 == 0)//每80万行写入一个文件
{
m_strSavePath = m_strFullFilePath + "\\" + "ic***-****-***-" + productName + "-" + customerLotNo + "-" + processBatch + "-" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + "-" + fileCount + ".csv";
fs = new FileStream(m_strSavePath, System.IO.FileMode.Create, System.IO.FileAccess.Write);
sw = new StreamWriter(fs, new System.Text.UnicodeEncoding());
sw.Write(sbData.ToString());
sw.Flush();
sw.Close();
sw.Dispose();
sbData.Clear();
sbData.Append(sbHeader);
fileCount++;
}
}
}
}
核心就是按照行读,再把自己数据处理成一行,再按照行写。
遇到的问题就是内存溢出,由于数据量大,转换速度快,一开始打算每读一百万行保存成一个文件,但是电脑配置有限,该成八十万就ok了。可以根据自己电脑实际情况来。
改了之后再重新传,速度飞快。几千万行的绝对十分钟之内。
网友评论