在园子里看过很多文章,关于设计模式,关于架构等等,我在这里谈谈一些软件的功能,为什么需要这样的功能。
我前段时间写了一个TXT与EXCEL为什么要互相转换的功能,可能有人会问,这样的功能有什么作用?是的,这小功能在软件开发上有很大的作用的。txt文本是没有格式的,但是excel文档是有格式的,将没有格式的东西转换为有格式的东西,可以方便别人阅读,除此之外,很多软件的服务端传给客户端的东西是没有格式的东西,就是一个字符串,客户端接收到这个字符串,如何格式化,变成我们需要的东西,比如说excel文档。反之,有个excel文档,也要将它变成字符串才能顺利地发给服务端,或者发给调用者。当然,可能有人会说传字符串的方式非常落后,现在都有webservice这个标准化的东西,webservice是有格式的,而且很好传输与解析,但是如果你后台是用C语言写,或者是更低级语言编写的,并没有类似于webservice的东西,那就只能传输字符流了。其实webservice传输的也是wsdl的文本,它本身也是一堆字符而已,只不过是通过一些组件变成我们需要的东西,例如类。webservice只是一个通用的标准,也可以制定属于自己的标准。
EXECL转换TXT:
首先,需要读取EXCEL文档,读取excel文档可以通过ADO.NET的Connection。
private OleDbConnection getCon(string excelPath)
{
try
{
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + excelPath + ";" + "Extended Properties=Excel 8.0;";
OleDbConnection conn = new OleDbConnection(strConn);
conn.Open();
return conn;
}
catch (Exception ex)
{
throw new ArgumentException("打开excel失败", ex.Message);
}
}
然后,需要读取excel文档的每一页,与读取excel的内容
/// <summary>
/// 获取excel页
/// </summary>
/// <param name="excelPath"></param>
/// <returns></returns>
public string[] getSheets(string excelPath)
{
OleDbConnection conn = getCon(excelPath);
try
{
DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" });
string[] strTableNames = new string[dtSheetName.Rows.Count];
int i = 0;
for (int k = 0; k < dtSheetName.Rows.Count; k++)
{
//把有下划线的excel页去掉
if (!dtSheetName.Rows[k]["TABLE_NAME"].ToString().Contains("_"))
{
strTableNames[i] = dtSheetName.Rows[k]["TABLE_NAME"].ToString();
i++;
}
}
return strTableNames;
}
catch (Exception ex)
{ throw ex; }
finally
{ conn.Close(); }
}
/// <summary>
/// 获取excel的数据
/// </summary>
/// <param name="excelPath"></param>
/// <param name="sheetName"></param>
/// <returns></returns>
public DataTable GetExcelDB(string excelPath,string sheetName)
{
OleDbConnection conn = getCon(excelPath);
try
{
DataTable dt = new DataTable();
OleDbDataAdapter myada = null;
string strExcel = "select * from [" + sheetName + "]";
myada = new OleDbDataAdapter(strExcel, conn);
myada.Fill(dt);
return dt;
}
catch (Exception ex)
{ throw ex; }
finally
{ conn.Close(); }
}
最后,生成TXT文本,因为txt文本是没有格式的,因此我们需要制定一些标准,我设定每个单元格的长度都为30个字节,excel的每一行对应txt的一行。如果单元格的长度是不一样的,可以制定一个list。有了标准,这样在txt转excel是才能成功。这里需要注意一点,中文字符与英文字符的节长度是不一样的,中文占两个字节,而英文是占1个字节,因此在转换的时候需要多做一些工作。
/// <summary>
/// 生成txt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGenerate_Click(object sender, EventArgs e)
{
if (txtExcelPath.Text.Trim() == "")
{
MessageBox.Show("请导入excel");
return;
}
if (cboSheet.Text.Trim() == "")
{
MessageBox.Show("没有存在的excel页");
return;
}
string colName = "";
string rowText = "";
StringBuilder strbui = new StringBuilder();
try
{
DataTable dt = GetExcelData.ExcelObj.GetExcelDB(txtExcelPath.Text.Trim(), cboSheet.Text.Trim());
for (int i = 0; i < dt.Columns.Count; i++)
{
string tempName = dt.Columns[i].ColumnName.Trim();
byte[] byte_len = Encoding.Default.GetBytes(tempName);
if (byte_len.Length < 30)
{
int k = 30 - byte_len.Length;
for (int t = k; t > 0; t--)
{
tempName += " ";
}
}
else
{
byte[] CutStr_Bytes1 = new byte[30];
Array.Copy(byte_len, 0, CutStr_Bytes1, 0, 30);
tempName = myEncoding.GetString(CutStr_Bytes1);
}
colName += tempName;
}
for (int i = 0; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
string tempName = dt.Rows[i][j].ToString();
byte[] byte_len = Encoding.Default.GetBytes(tempName);
if (byte_len.Length < 30)
{
int k = 30 - byte_len.Length;
for (int t = k; t > 0; t--)
{
tempName += " ";
}
}
else
{
byte[] CutStr_Bytes1 = new byte[30];
Array.Copy(byte_len, 0, CutStr_Bytes1, 0, 30);
tempName = myEncoding.GetString(CutStr_Bytes1);
}
strbui.Append(tempName);
}
strbui.Append("\r\n");
}
rowText = strbui.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
try
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "文本文件|*.txt";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
StreamWriter streamWriter = new StreamWriter(saveFileDialog.FileName, false, System.Text.Encoding.GetEncoding("gb2312"));
streamWriter.Write(colName + "\r\n" + rowText);
streamWriter.Close();
}
}
catch (Exception ex)
{
MessageBox.Show("保存txt失败" + ex.Message);
}
}
TXT转换EXECL: 在txt转换excel的过程中,首先需要获取txt文本
/// <summary>
///
/// </summary>
StreamReader reader = null;
/// <summary>
///
/// </summary>
Encoding myEncoding = Encoding.GetEncoding("GB2312");
/// <summary>
/// 导入txt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnImportTxt_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.InitialDirectory = "D:\\";
openFileDialog.Filter = "TXT文件|*.txt";
openFileDialog.RestoreDirectory = true;
openFileDialog.FilterIndex = 1;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
string fName = openFileDialog.FileName;
textBox2.Text = fName;
reader = new StreamReader(fName, System.Text.Encoding.GetEncoding("GB2312"));
}
}
然后对文本进行处理,用 reader.ReadLine()一行行地往下读,每读一行处理一行,直到读完为止。处理的时候需要把字符串均等平分,每30个字节写一个单元格。
/// <summary>
/// 把字符串均等平分
/// </summary>
/// <param name="SourceString"></param>
/// <returns></returns>
private string[] spitText(string SourceString)
{
int length = 30;
int len = 0;
byte[] SourceStr_Bytes = myEncoding.GetBytes(SourceString);
byte[] CutStr_Bytes1 = new byte[length];
if (SourceStr_Bytes.Length % length != 0)
len = SourceStr_Bytes.Length / length + 1;
else
len = SourceStr_Bytes.Length / length;
string[] array = new string[len];
int i, j = 0;
for (i = 0; (i + length) <= SourceStr_Bytes.Length && SourceStr_Bytes.Length >= i; )
{
Array.Copy(SourceStr_Bytes, i, CutStr_Bytes1, 0, length);
array[j] = myEncoding.GetString(CutStr_Bytes1);
j++;
i = i + length;
}
if (SourceStr_Bytes.Length % length != 0)
{
Array.Copy(SourceStr_Bytes, SourceStr_Bytes.Length - i, CutStr_Bytes1, 0, length);
array[j] = myEncoding.GetString(CutStr_Bytes1);
}
return array;
}
/// <summary>
/// 生成txt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnGenTxt_Click(object sender, EventArgs e)
{
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "文本文件|*.xls";
if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
StreamWriter sw = new StreamWriter(saveFileDialog.FileName, true, System.Text.Encoding.GetEncoding("GB2312"));
string str = "";
if (reader == null)
{
MessageBox.Show("请导入txt");
return;
}
try
{
//写标题
string headText = reader.ReadLine();
string[] array = spitText(headText);
for (int i = 0; i < array.Length; i++)
{
array[i] += "\t";
str += array[i];
}
sw.WriteLine(str);
//写内容
string text;
while ((text = reader.ReadLine()) != null)
{
string tempStr = "";
string[] arrayText = spitText(text);
for (int f = 0; f < arrayText.Length; f++)
{
tempStr += arrayText[f] + "\t";
}
sw.WriteLine(tempStr);
}
sw.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
sw.Close();
}
}
}
好了,到这里,TXT月EXCEL的互相转换功能就做好了,源码没找到地方上传,改天找个好的网盘上传。