从DataSet导出Txt

网上已经存在很多从DataSet导出到Word、Excel、Txt等的文章了,为什么还要写这篇文章呢,因为搜索了好长时间都没有找到符合要求的(不代表没有),只好自己动手写一个。后面我还遇到了问题,希望园子里的朋友帮忙解决一下,看有没有更好的办法。

在这篇文章中,我涉及两个导出的问题。第一个问题是导出的每一列根据这一列的长度自动分配宽度,这样说还是不够明了,下面通过例子来看。

首先,构造我们的DataSet。本来想从数据库中查询得到,这样虽然麻烦点,但是更直接。

DataSet ds = new DataSet();
DataTable table = new DataTable();
DataColumn[] columns = new DataColumn[7];
columns[0] = new DataColumn("EmpNo");
columns[1] = new DataColumn("EmpName");
columns[2] = new DataColumn("Dept");
columns[3] = new DataColumn("Post");
columns[4] = new DataColumn("Salary");
columns[5] = new DataColumn("Bank");
columns[6] = new DataColumn("BankNo");
table.Columns.AddRange(columns);
DataRow row1 = table.NewRow();
row1["EmpNo"] = "1001";
row1["EmpName"] = "刘德华";
row1["Dept"] = "办公室";
row1["Post"] = "总经理";
row1["Salary"] = 6000;
row1["Bank"] = "建设银行";
row1["BankNo"] = "5475694879437594";
DataRow row2 = table.NewRow();
row2["EmpNo"] = "1002";
row2["EmpName"] = "周迅";
row2["Dept"] = "财务";
row2["Post"] = "出纳";
row2["Salary"] = 4000;
row2["Bank"] = "建设银行";
row2["BankNo"] = "5475695489548395";
DataRow row3 = table.NewRow();
row3["EmpNo"] = "1003";
row3["EmpName"] = "abc";
row3["Dept"] = "信息部";
row3["Post"] = "程序员";
row3["Salary"] = 5000;
row3["Bank"] = "建设银行";
row3["BankNo"] = "5475763489548395";
table.Rows.Add(row1);
table.Rows.Add(row2);
table.Rows.Add(row3);
ds.Tables.Add(table);

在上面的代码中有三条数据。

第二,写导出的方法。

/// <summary>
/// DataSet导出为Txt
/// </summary>
/// <param name="ds"></param>
/// <param name="fileName">导出txt文件名</param>
/// <param name="page"></param>
public static void ToTxt(DataSet ds, string fileName, Page page)
{
    StringBuilder sb = new StringBuilder();
    DataTable table = ds.Tables[0];
    DataRowCollection rows = table.Rows;
    DataColumnCollection columns = table.Columns;
    //行数
    int rowCount = rows.Count;
    //列数
    int columnCount = columns.Count;
    //每列的最大长度
    int[] columnMaxLength = new int[columnCount];

    //遍历所有的记录获得每列的最大长度
    for (int i = 0; i < columnCount; i++)
    {
        int[] tmps = new int[rowCount];
        for (int j = 0; j < rowCount; j++)
        {
            tmps[j] = System.Text.Encoding.Default.GetByteCount(rows[j][i].ToString());
        }
        columnMaxLength[i] = ArrayMaxValue(tmps);
    }
    //将上面取的最大长度与列名比较
    for (int i = 0; i < columnCount; i++)
    {
        if (columnMaxLength[i] < System.Text.Encoding.Default.GetByteCount(columns[i].ColumnName))
        {
            columnMaxLength[i] = System.Text.Encoding.Default.GetByteCount(columns[i].ColumnName);
        }
    }
    //将列名附加到字符串
    for (int i = 0; i < columnCount; i++)
    {
        int a = columnMaxLength[i] - System.Text.Encoding.Default.GetByteCount(columns[i].ColumnName);
        StringBuilder sb1 = new StringBuilder(a);
        //每列之间间隔3
        for (int j = 0; j < a + 3; j++)
        {
            sb1.Append(" ");
        }
        sb.Append(columns[i].ColumnName).Append(sb1.ToString());
    }
    sb.AppendLine();
    sb.AppendLine();

    //将记录附加到字符串
    for (int i = 0; i < rowCount; i++)
    {
        for (int j = 0; j < columnCount; j++)
        {
            int a = columnMaxLength[j] - System.Text.Encoding.Default.GetByteCount(rows[i][j].ToString());
            StringBuilder sb1 = new StringBuilder(a);
            for (int k = 0; k < a + 3; k++)
            {
                sb1.Append(" ");
            }

            sb.Append(rows[i][j]).Append(sb1.ToString());
        }
        sb.AppendLine();
    }

    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Buffer = false;
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
    HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpContext.Current.Server.HtmlEncode(fileName) + ".txt");
    HttpContext.Current.Response.ContentType = "text/plain";
    page.EnableViewState = false;
    HttpContext.Current.Response.Write(sb.ToString());
    HttpContext.Current.Response.End();
}

/// <summary>
/// 取数组的最大值
/// </summary>
/// <param name="arr"></param>
/// <returns></returns>
private static int ArrayMaxValue(int[] arr)
{
    int maxInt = arr[0];
    for (int i = 0; i < arr.Length; i++)
    {
        if (arr[i] > maxInt)
        {
            maxInt = arr[i];
        }
    }
    return maxInt;
}

在上面的方法中,应该可以改正减少很多代码,如果感兴趣的朋友可以修改。方法中,我使用的是字符串的字节长度,而不是字符串的长度,如果使用字符串长度,一个英文字母和一个汉字的长度都是1,显然汉字要宽。我发现一个汉字的宽度和2个英文字母的宽度差不多(看着差不多),一个汉字又等于2个字节,所以就是用了字节长度。

最后,导出的效果如下图所示:

QQ截图20120105235429

public static void ToTxt(DataSet ds, string fileName, Page page)
{
    StringBuilder sb = new StringBuilder();
    DataTable table = ds.Tables[0];
    DataRowCollection rows = table.Rows;
    DataColumnCollection columns = table.Columns;
    int rowCount = rows.Count;
    int columnCount = columns.Count;

    int k = 1;
    for (int i = 0; i < rows.Count; i++)
    {
        decimal factSalary = Convert.ToDecimal(rows[i]["FactSalary"]);
        int a = (int)(factSalary - factSalary % 5000) / 5000;
        if (a > 0)
        {
            for (int j = 0; j < a; j++)
            {
                sb.Append(i + k + j).Append(",");
                sb.Append(rows[i]["BankNo"].ToString()).Append(",");
                sb.Append(rows[i]["EmpName"].ToString()).Append(",");
                sb.Append(5000).Append(",");
                sb.Append("公务报销");
                sb.AppendLine();
            }
            k += a;
            sb.Append(i + k).Append(",");
            sb.Append(rows[i]["BankNo"].ToString()).Append(",");
            sb.Append(rows[i]["EmpName"].ToString()).Append(",");
            sb.Append(factSalary % 5000).Append(",");
            sb.Append("公务报销");
            sb.AppendLine();
        }
        else
        {
            sb.Append(i + k).Append(",");
            sb.Append(rows[i]["BankNo"].ToString()).Append(",");
            sb.Append(rows[i]["EmpName"].ToString()).Append(",");
            sb.Append(rows[i]["FactSalary"]).Append(",");
            sb.Append("公务报销");
            sb.AppendLine();
        }
    }
    HttpContext.Current.Response.Clear();
    HttpContext.Current.Response.Buffer = false;
    HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.UTF8;
    HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpContext.Current.Server.HtmlEncode(fileName) + ".txt");
    HttpContext.Current.Response.ContentType = "text/plain";
    page.EnableViewState = false;
    HttpContext.Current.Response.Write(sb.ToString());
    HttpContext.Current.Response.End();
}

第二个问题就是导出的每个TXT中,总的金额不能超过10万,单笔不能超过5000,如果超过5000,就要进行拆分。

我写了一个方法实现了单笔超过5000的进行拆分,但是一个TXT中总金额不超过10万,还没有写,一种解决方案就是先创建一个文件,将不超过10万的导入到这个文件中,然后再创建一个文件,继续导入到这个文件中,如此,直到导出完成。

稍微修改上面的DataSet数据,金额分别修改为6000,5001,10001最后导出的效果如下图所示:

QQ截图20120106001544 

时间不早了,希望园子里的朋友能给出更好的解决方案,谢谢了!

posted @ 2012-01-06 00:18  BobTian  阅读(4045)  评论(7编辑  收藏  举报