表格中某一列相邻内容一样的合并行

原需求:生成的word版、PDF版合同中多行产品最后一列备注内容太多,不同产品有时备注又一样,这样每一列产品都有一个内容很长的备注,导致整个合同的排版不美观,占空间也比较大,如图1。因此用户提出:将不同产品行相邻的备注内容一样的进行合并,效果如图2。
表格中某一列相邻内容一样的合并行
图1

表格中某一列相邻内容一样的合并行
图2(word版)

表格中某一列相邻内容一样的合并行
图3(PDF版)

1.word版合同

原来方法:直接在后台绑定repeater控件(控件放在前台一个div中),点击导出按钮直接将该div转换成字符数组写入HTTP响应输出流,但无法实现图2效果。

解决思路:因为数据是动态绑定的,所以在创建表格某一行时还不知道需要合并几行,而table又不支持向上合并。因此一个可行的方法就是先将合并的行数定义为特殊字符,在将整个表格遍历结束之后再将特殊字符替换掉。

实现方法:将数据绑定改为字符串拼接,在第一次循环时设置rowspan,在第二次之后开始判断备注是否一样,若一样该行就结束,否则需要再加带rowspan的一列。并且在每次循环时记录相同的行数,每次出现不一样的行时就将上次的行数拼接,这样循环结束之后就得到一个类似于 “,3,1” 的字符串,表示表格的前三行备注一样。最后将该字符串转换成数组arr_str,以数组长度进行遍历拼接成的html(带有特殊字符),将特殊字段替换成相应的数组值。代码如下:

//绑定合同产品
protected void BindProduct(int id, int uid)
{
    DataTable dt = bllProduct.AgreementProListByAgridUid(id, uid);
    string strHtml = "";
    string DeliveryDate = "", HomeFee = "", Installation = "", PNote = "";
    int count = 1, index = 1;
    string strs = "";
    int[] array = new int[dt.Rows.Count];
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        strHtml += "<tr>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + dt.Rows[i]["ProductName"] + "</td>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + dt.Rows[i]["Brand"] + "</td>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + dt.Rows[i]["Model"] + "</td>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + dt.Rows[i]["SellingPrice"] + "</td>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + dt.Rows[i]["Number"] + "(" + dt.Rows[i]["Unit"] + ")</td>";
        strHtml += "<td style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000;\">" + Convert.ToSingle(dt.Rows[i]["SellingPrice"]) * Convert.ToInt32(dt.Rows[i]["Number"]) + "</td>";
        if (i == 0)
        {
            strHtml += "<td rowspan=\"@_0\" style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000; border-right: 1px solid #000;\">" + (dt.Rows[i]["DeliveryDate"] != DBNull.Value ? "货期:" + dt.Rows[i]["DeliveryDate"] + "<br/>" : "") + (dt.Rows[i]["HomeFee"] != DBNull.Value ? "运费:" + (dt.Rows[i]["HomeFee"].ToString() == "1" ? "送货上门,不含任何搬卸及上楼费用" : dt.Rows[i]["HomeFee"].ToString() == "2" ? "物流点自提" : dt.Rows[i]["HomeFee"].ToString() == "3" ? "不含运费" : "送货上门,含卸车上楼费用") + "<br/>" : "") + (dt.Rows[i]["Installation"] != DBNull.Value ? "安调说明:" + (dt.Rows[i]["Installation"].ToString() == "1" ? "上门指导安装调试" : dt.Rows[i]["Installation"].ToString() == "2" ? "出厂前已调试无需安装" : "出厂前已调试,可电话指导安装") + "<br/>" : "") + (dt.Rows[i]["PNote"] != DBNull.Value ? dt.Rows[i]["PNote"] : "") + "</td>";
        }
        if (i > 0)
        {
            DeliveryDate = dt.Rows[i - 1]["DeliveryDate"].ToString();
            HomeFee = dt.Rows[i - 1]["HomeFee"].ToString();
            Installation = dt.Rows[i - 1]["Installation"].ToString();
            PNote = dt.Rows[i - 1]["PNote"].ToString();
        }
        if (DeliveryDate == dt.Rows[i]["DeliveryDate"].ToString() && HomeFee == dt.Rows[i]["HomeFee"].ToString() && Installation == dt.Rows[i]["Installation"].ToString() && PNote == dt.Rows[i]["PNote"].ToString())
        {
            count++;
        }
        else if(i > 0)
        {
            strs += "," + count;
            count = 1;
            strHtml += "<td rowspan=\"@_" + index + "\" style=\"border-left: 1px solid #000; border-top: 1px solid #000; border-bottom: 1px solid #000; border-right: 1px solid #000;\">" + (dt.Rows[i]["DeliveryDate"] != DBNull.Value ? "货期:" + dt.Rows[i]["DeliveryDate"] + "<br/>" : "") + (dt.Rows[i]["HomeFee"] != DBNull.Value ? "运费:" + (dt.Rows[i]["HomeFee"].ToString() == "1" ? "送货上门,不含任何搬卸及上楼费用" : dt.Rows[i]["HomeFee"].ToString() == "2" ? "物流点自提" : dt.Rows[i]["HomeFee"].ToString() == "3" ? "不含运费" : "送货上门,含卸车上楼费用") + "<br/>" : "") + (dt.Rows[i]["Installation"] != DBNull.Value ? "安调说明:" + (dt.Rows[i]["Installation"].ToString() == "1" ? "上门指导安装调试" : dt.Rows[i]["Installation"].ToString() == "2" ? "出厂前已调试无需安装" : "出厂前已调试,可电话指导安装") + "<br/>" : "") + (dt.Rows[i]["PNote"] != DBNull.Value ? dt.Rows[i]["PNote"] : "") + "</td>";
            index++;
        }
        if (i == dt.Rows.Count - 1)
        {
            strs += "," + count;
        }
        strHtml += "</tr>";
    }
    strs = strs.Length > 0 ? strs.Substring(1) : "";
    string[] arr_str = strs.Split(',');

    for (int i = 0; i < arr_str.Length; i++)
    {
        if (strHtml.Contains("@_" + i))
        {
            strHtml = strHtml.Replace("@_" + i, arr_str[i].ToString());
        }
    }
    this.tbody.InnerHtml = strHtml;
}

2.PDF版合同

难点:与html不同的是,由于生成PDF合同是用组件iTextSharp实现,但这个组件却没有Rowspan方法,只有一个Colspan。

解决思路:转换思维,要实现最后一列的Rowspan的效果,只需要将前面几行几列作为一个table嵌套到外面的table中。

实现方法:需要先确定每次要合并多少行,即html中提到的数组arr_str。以数组的长度作为遍历条件,每次遍历需要创建一次table,在这层循环中再嵌套一个循环,内层循环以外层循环的数组值作为遍历条件,即有几个行相同的就遍历几次,代表外层这个表格有几行。具体代码如下:

PdfPTable t2 = new PdfPTable(7);
float[] widths2 = new float[] { 2f, 1f, 1f, 1f, 1f, 1f, 2f };
t2.SpacingBefore = 10f;
t2.SpacingAfter = 10f;
t2.SetWidths(widths2);

t2.AddCell(new PdfPCell(new Paragraph("产品名称", font10)));
t2.AddCell(new PdfPCell(new Phrase("品牌", font10)));
t2.AddCell(new PdfPCell(new Phrase("规格/型号", font10)));
t2.AddCell(new PdfPCell(new Phrase("单价(元)", font10)));
t2.AddCell(new PdfPCell(new Phrase("数量", font10)));//括号后单位动态获取
t2.AddCell(new PdfPCell(new Phrase("总额(元)", font10)));
t2.AddCell(new PdfPCell(new Phrase("备注", font10)));

DataTable dtP = bllProduct.AgreementProListByAgridUid(model.id, model.UId);

string strs = "";
string DeliveryDate = "", HomeFee = "", Installation = "", PNote = "";
int count = 1;
for (int k = 0; k < dtP.Rows.Count; k++)
{
    if (k > 0)
    {
        DeliveryDate = dtP.Rows[k - 1]["DeliveryDate"].ToString();
        HomeFee = dtP.Rows[k - 1]["HomeFee"].ToString();
        Installation = dtP.Rows[k - 1]["Installation"].ToString();
        PNote = dtP.Rows[k - 1]["PNote"].ToString();
    }
    if (DeliveryDate == dtP.Rows[k]["DeliveryDate"].ToString() && HomeFee == dtP.Rows[k]["HomeFee"].ToString() && Installation == dtP.Rows[k]["Installation"].ToString() && PNote == dtP.Rows[k]["PNote"].ToString())
    {
        count++;
    }
    else if (k > 0)
    {
        strs += "," + count;
        count = 1;
    }
    if (k == dtP.Rows.Count - 1)
    {
        strs += "," + count;
    }
}
strs = strs.Length > 0 ? strs.Substring(1) : "";
string[] arr_str = strs.Split(',');

totalAmount = 0;
int m = 0;
for (int j = 0; j < arr_str.Length; j++)
{
    PdfPTable pro_dt = new PdfPTable(6);
    float[] pro_width = new float[] { 2f, 1f, 1f, 1f, 1f, 1f };
    pro_dt.SetWidths(pro_width);
    float minHeight = 50f;
    if (int.Parse(arr_str[j]) > 2)
    {
        minHeight = 30f;
    }
    for (int n = 0; n < int.Parse(arr_str[j]); n++)
    {
        var ProductName = new PdfPCell(new Phrase(dtP.Rows[m]["ProductName"].ToString(), font10));
        ProductName.VerticalAlignment = Element.ALIGN_MIDDLE;
        ProductName.MinimumHeight = minHeight;
        pro_dt.AddCell(ProductName);
        var Brand = new PdfPCell(new Phrase(dtP.Rows[m]["Brand"].ToString(), font10));
        Brand.VerticalAlignment = Element.ALIGN_MIDDLE;
        Brand.MinimumHeight = minHeight;
        pro_dt.AddCell(Brand);
        var Model = new PdfPCell(new Phrase(dtP.Rows[m]["Model"].ToString(), font10));
        Model.VerticalAlignment = Element.ALIGN_MIDDLE;
        Model.MinimumHeight = minHeight;
        pro_dt.AddCell(Model);
        var SellingPrice = new PdfPCell(new Phrase(dtP.Rows[m]["SellingPrice"].ToString(), font10));
        SellingPrice.VerticalAlignment = Element.ALIGN_MIDDLE;
        SellingPrice.MinimumHeight = minHeight;
        pro_dt.AddCell(SellingPrice);
        var Number_Unit = new PdfPCell(new Phrase(dtP.Rows[m]["Number"].ToString() + "(" + dtP.Rows[m]["Unit"].ToString() + ")", font10));
        Number_Unit.VerticalAlignment = Element.ALIGN_MIDDLE;
        Number_Unit.MinimumHeight = minHeight;
        pro_dt.AddCell(Number_Unit);
        float totalPer = Convert.ToSingle(dtP.Rows[m]["SellingPrice"]) * Convert.ToSingle(dtP.Rows[m]["Number"]);
        totalAmount += totalPer;
        var cell_total = new PdfPCell(new Phrase(totalPer.ToString(), font10));
        cell_total.VerticalAlignment = Element.ALIGN_MIDDLE;
        cell_total.MinimumHeight = minHeight;
        pro_dt.AddCell(cell_total);
        m++;
    }
    PdfPCell pro_cell = new PdfPCell(pro_dt);
    pro_cell.Colspan = 6;
    pro_cell.Padding = 0f;
    t2.AddCell(pro_cell);
    #region
    PdfPCell remarkcell = new PdfPCell();
    remarkcell.AddElement(new Paragraph((dtP.Rows[m-1]["DeliveryDate"] != DBNull.Value ? "货期:" + dtP.Rows[m-1]["DeliveryDate"] : ""), font10));
    string homefee = "";
    if (dtP.Rows[m-1]["HomeFee"] != DBNull.Value)
    {
        switch (dtP.Rows[m-1]["HomeFee"].ToString())
        {
            case "1":
                homefee = "送货上门,不含任何搬卸及上楼费用";
                break;
            case "2":
                homefee = "物流点自提";
                break;
            case "3":
                homefee = "不含运费";
                break;
            case "4":
                homefee = "送货上门,含卸车上楼费用";
                break;
        }
    }
    remarkcell.AddElement(new Paragraph(dtP.Rows[m-1]["HomeFee"] != DBNull.Value ? "运费:" + homefee : "", font10));
    string installation = "";
    if (dtP.Rows[m-1]["Installation"] != DBNull.Value)
    {
        switch (dtP.Rows[m-1]["Installation"].ToString())
        {
            case "1":
                installation = "上门指导安装调试";
                break;
            case "2":
                installation = "出厂前已调试无需安装";
                break;
            case "3":
                installation = "出厂前已调试,可电话指导安装";
                break;
        }
    }
    remarkcell.AddElement(new Paragraph(dtP.Rows[m-1]["Installation"] != DBNull.Value ? "安调说明:" + installation : "", font10));
    remarkcell.AddElement(new Paragraph(dtP.Rows[m-1]["PNote"] != null ? dtP.Rows[m-1]["PNote"].ToString() : "", font10));
    remarkcell.VerticalAlignment = Element.ALIGN_MIDDLE;
    t2.AddCell(remarkcell);
    #endregion
}

猜你喜欢

转载自blog.csdn.net/yiyelanxin/article/details/79634690
今日推荐