资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

怎么在NPOI中实现两级分组合并功能-创新互联

本篇文章为大家展示了怎么在NPOI中实现两级分组合并功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

王益网站建设公司成都创新互联,王益网站设计制作,有大型网站制作公司丰富经验。已为王益上千家提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的王益做网站的公司定做!
/// 
/// 根据模版导出Excel -- 特别处理,每个分组带合计
/// 
/// 源DataTable
/// 需要导出的对应的列字段 例:string[] cellKeys = { "Date","Remarks" };
/// 要保存的文件名称(包含后缀) 例:"要保存的文件名.xls"
/// 模版文件名(包含路径后缀) 例:"模板文件名.xls"
/// 从第几行开始创建数据行,第一行为0
/// 值相同时,可合并的前几列 最多支持2列 1=只合并第一列,2=判断前2列
/// 是否覆盖数据,=false,将把原数据下移。=true,将覆盖插入行后面的数据
/// 是否带小计/合计项
/// 是否添加总计项
/// 是否导出成功
public static bool Export2Template2(DataTable source, string[] cellKeys, string strFileName, string templateFile, int rowIndex, int mergeColumns, bool isConver, bool isTotal, bool addAllTotal)
{
 bool bn = false;
 int cellCount = cellKeys.Length; //总列数,第一列为0
 // IWorkbook workbook = null;
 HSSFWorkbook workbook = null;
 string temp0 = "", temp1 = "";
 int start0 = 0, start1 = 0; // 记录1,2列值相同的开始序号
 int end0 = 0, end1 = 0;// 记录1,2列值相同的结束序号
 
 try
 {
  using (FileStream file = new FileStream(templateFile, FileMode.Open, FileAccess.Read))
  {
   workbook = new HSSFWorkbook(file);
  }
 
  #region 定义四类数据的单元格样式
  // 内容数据格式 -- 数值
  ICellStyle styleNum = workbook.CreateCellStyle();
  styleNum.BorderBottom = BorderStyle.Thin;
  styleNum.BorderLeft = BorderStyle.Thin;
  styleNum.BorderRight = BorderStyle.Thin;
  styleNum.BorderTop = BorderStyle.Thin;
  // styleNum.VerticalAlignment = VerticalAlignment.Center;
  // styleNum.Alignment = HorizontalAlignment.Center;
 
  // 内容数据格式 -- 字符串(做居中处理)
  ICellStyle styleStr = workbook.CreateCellStyle();
  styleStr.BorderBottom = BorderStyle.Thin;
  styleStr.BorderLeft = BorderStyle.Thin;
  styleStr.BorderRight = BorderStyle.Thin;
  styleStr.BorderTop = BorderStyle.Thin;
  styleStr.VerticalAlignment = VerticalAlignment.Center;
  styleStr.Alignment = HorizontalAlignment.Center;
 
  // 汇总数据格式 -- 数值
  ICellStyle styleTotalNum = workbook.CreateCellStyle();
  styleTotalNum.BorderBottom = BorderStyle.Thin;
  styleTotalNum.BorderLeft = BorderStyle.Thin;
  styleTotalNum.BorderRight = BorderStyle.Thin;
  styleTotalNum.BorderTop = BorderStyle.Thin;
  styleTotalNum.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
  styleTotalNum.FillPattern = FillPattern.SolidForeground;
  styleTotalNum.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
  // 设置字体颜色
  HSSFFont ffont0 = (HSSFFont)workbook.CreateFont();
  // ffont0.FontHeight = 14 * 14;
  // ffont0.FontName = "宋体";
  ffont0.IsBold = true;
  //ffont0.Color = HSSFColor.Red.Index;
  styleTotalNum.SetFont(ffont0);
 
  // 汇总数据格式 -- 字符串(做居中处理)
  ICellStyle styleTotalStr = workbook.CreateCellStyle();
  styleTotalStr.BorderBottom = BorderStyle.Thin;
  styleTotalStr.BorderLeft = BorderStyle.Thin;
  styleTotalStr.BorderRight = BorderStyle.Thin;
  styleTotalStr.BorderTop = BorderStyle.Thin;
  styleTotalStr.VerticalAlignment = VerticalAlignment.Center;
  styleTotalStr.Alignment = HorizontalAlignment.Center;
  styleTotalStr.FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Grey25Percent.Index;
  styleTotalStr.FillPattern = FillPattern.SolidForeground;
  // 设置字体颜色
  HSSFFont ffont1 = (HSSFFont)workbook.CreateFont();
  // ffont1.FontHeight = 14 * 14;
  // ffont1.FontName = "宋体";
  ffont1.IsBold = true;
  //ffont.Color = HSSFColor.Red.Index;
  styleTotalStr.SetFont(ffont1);
  #endregion
 
  ISheet sheet = workbook.GetSheetAt(0); // 打开第一个sheet页
  if (sheet != null && source != null && source.Rows.Count > 0) // 模板内容为空,不做处理
  {
   IRow row;
   for (int i = 0, len = source.Rows.Count; i < len; i++)
   {
    if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移
 
    #region 第一行,写入数据后,对变量赋初值
    if (i == 0) // 第一行,赋初值
    {
     row = sheet.CreateRow(rowIndex);
     #region 创建列并插入数据
     //创建列并插入数据
     for (int index = 0; index < cellCount; index++)
     {
      ICell cell = row.CreateCell(index);
 
      string strValue = !(source.Rows[i][cellKeys[index]] is DBNull) ? source.Rows[i][cellKeys[index]].ToString() : string.Empty;
      // 其它列数据,数值进行汇总
      switch (source.Columns[cellKeys[index]].DataType.ToString())
      {
       case "System.Int16": //整型
       case "System.Int32":
       case "System.Int64":
       case "System.Byte":
        int intV = 0;
        int.TryParse(strValue, out intV);
        cell.CellStyle = styleNum; // 设置格式
        cell.SetCellValue(intV);
        break;
       case "System.Decimal": //浮点型
       case "System.Double":
       case "System.Single":
        double doubV = 0;
        double.TryParse(strValue, out doubV);
        cell.CellStyle = styleNum; // 设置格式
        cell.SetCellValue(doubV);
        break;
       default:
        cell.CellStyle = styleStr; // 设置格式
        cell.SetCellValue(strValue);
        break;
      }
     }
     #endregion
 
     if (mergeColumns > 0)
     {
      temp0 = source.Rows[i][cellKeys[0]].ToString(); // 保存第1列值
      start0 = rowIndex;
      end0 = rowIndex;
     }
     if (mergeColumns > 1)
     {
      temp1 = source.Rows[i][cellKeys[1]].ToString(); // 保存第2列值     
      start1 = rowIndex;
      end1 = rowIndex;
     }
 
     rowIndex++;
     continue;
    }
    #endregion
 
    // 不是第一行数据的处理
    // 判断1列值变化没
    string cellText0 = source.Rows[i][cellKeys[0]].ToString();
    if (temp0 != cellText0) // 第1列值有变化
    {
     #region 第2列要合并
     if (mergeColumns > 1) // 第2列要合并
     {
      if (start1 != end1) // 开始行和结束行不相同,才进行合并
      {
       CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列
       sheet.AddMergedRegion(region1);
      }
 
      #region 第2列加小计
      if (isTotal) // 加小计
      {
       if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移
 
       IRow rowTotal1 = sheet.CreateRow(rowIndex);
       //创建列并插入数据
       #region 插入小计数据
       for (int index = 0; index < cellCount; index++)
       {
        object obj1;
        ICell newcell = rowTotal1.CreateCell(index);
        if (index == 0) //第1列
        {
         newcell.CellStyle = styleTotalStr;
         newcell.SetCellValue(temp0);
         continue;
        }
        if (index == 1) // 第2列
        {
         newcell.CellStyle = styleTotalStr;
         newcell.SetCellValue("小计");
         continue;
        }
 
        // 其它列数据,数值进行汇总
        switch (source.Columns[cellKeys[index]].DataType.ToString())
        {
         case "System.Int16": //整型
         case "System.Int32":
         case "System.Int64":
         case "System.Byte":
          obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));
          int intV = 0;
          int.TryParse(obj1.ToString(), out intV);
          newcell.CellStyle = styleTotalNum;
          newcell.SetCellValue(intV);
          break;
         case "System.Decimal": //浮点型
         case "System.Double":
         case "System.Single":
          obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));
          double doubV = 0;
          double.TryParse(obj1.ToString(), out doubV);
          newcell.CellStyle = styleTotalNum;
          newcell.SetCellValue(doubV);
          break;
         default:
          newcell.CellStyle = styleTotalStr;
          newcell.SetCellValue("");
          break;
        }
       }
       #endregion
 
       // 合并小计
       CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计
       sheet.AddMergedRegion(region0);
 
      }
      #endregion
      temp1 = source.Rows[i][cellKeys[1]].ToString();
      end0++;
      rowIndex++;
     }
     #endregion
 
     #region 第1列要合并
     if (mergeColumns > 0) // 第1列要合并
     {
      if (start0 != end0) // 开始行和结束行不相同,才进行合并
      {
       CellRangeAddress region0 = new CellRangeAddress(start0, end0, 0, 0); // 合并第二列
       sheet.AddMergedRegion(region0);
      }
 
      #region 第1列加合计
      if (isTotal) // 加合计
      {
       if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移
 
       IRow rowTotal0 = sheet.CreateRow(rowIndex);
       //创建列并插入数据
       #region 加合计列
       for (int index = 0; index < cellCount; index++)
       {
        object obj1;
        ICell newcell = rowTotal0.CreateCell(index);
        if (index == 0)
        {
         newcell.CellStyle = styleTotalStr;
         newcell.SetCellValue("合计"); //第1列
         continue;
        }
        if (index == 1)
        {
         newcell.CellStyle = styleTotalStr;
         newcell.SetCellValue(""); // 第2列
         continue;
        }
 
        switch (source.Columns[cellKeys[index]].DataType.ToString())
        {
         case "System.Int16": //整型
         case "System.Int32":
         case "System.Int64":
         case "System.Byte":
          obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' ", cellKeys[0], temp0));
          int intV = 0;
          int.TryParse(obj1.ToString(), out intV);
          newcell.CellStyle = styleTotalNum;
          newcell.SetCellValue(intV);
          break;
         case "System.Decimal": //浮点型
         case "System.Double":
         case "System.Single":
          obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' ", cellKeys[0], temp0));
          double doubV = 0;
          double.TryParse(obj1.ToString(), out doubV);
          newcell.CellStyle = styleTotalNum;
          newcell.SetCellValue(doubV);
          break;
         default:
          newcell.CellStyle = styleTotalStr;
          newcell.SetCellValue("");
          break;
        }
       }
       #endregion
 
       // 合并合计
       CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并合计
       sheet.AddMergedRegion(region0);
 
       end0++;
       rowIndex++;
      }
      #endregion
      temp0 = cellText0;
     }
     #endregion
 
     // 重新赋值
     start0 = rowIndex;
     end0 = rowIndex;
     start1 = rowIndex;
     end1 = rowIndex;
    }
    else // 第1列值没有变化
    {
     end0++;
     // 判断第2列是否有变化
     string cellText1 = source.Rows[i][cellKeys[1]].ToString();
     if (cellText1 != temp1) // 第1列没变,第2列变化
     {
      #region 第2列要合并
      if (mergeColumns > 1) // 第2列要合并
      {
       if (start1 != end1) // 开始行和结束行不相同,才进行合并
       {
        CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列
        sheet.AddMergedRegion(region1);
       }
 
       #region 第2列加小计
       if (isTotal) // 加小计
       {
        if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移
 
        IRow rowTotal1 = sheet.CreateRow(rowIndex);
        //创建列并插入数据
        #region 插入小计数据
        for (int index = 0; index < cellCount; index++)
        {
         object obj1;
         ICell newcell = rowTotal1.CreateCell(index);
         if (index == 0) //第1列
         {
          newcell.CellStyle = styleTotalStr;
          newcell.SetCellValue(temp0);
          continue;
         }
         if (index == 1) // 第2列
         {
          newcell.CellStyle = styleTotalStr;
          newcell.SetCellValue("小计");
          continue;
         }
 
         // 其它列数据,数值进行汇总
         switch (source.Columns[cellKeys[index]].DataType.ToString())
         {
          case "System.Int16": //整型
          case "System.Int32":
          case "System.Int64":
          case "System.Byte":
           obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));
           int intV = 0;
           int.TryParse(obj1.ToString(), out intV);
           newcell.CellStyle = styleTotalNum;
           newcell.SetCellValue(intV);
           break;
          case "System.Decimal": //浮点型
          case "System.Double":
          case "System.Single":
           obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));
           double doubV = 0;
           double.TryParse(obj1.ToString(), out doubV);
           newcell.CellStyle = styleTotalNum;
           newcell.SetCellValue(doubV);
           break;
          default:
           newcell.CellStyle = styleTotalStr;
           newcell.SetCellValue("");
           break;
         }
        }
        #endregion
        // 合并小计
        CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计
        sheet.AddMergedRegion(region0);
 
        end0++;
        rowIndex++;
       }
       temp1 = cellText1; // 要合并,才进行重新赋值
       start1 = rowIndex;
       end1 = rowIndex;
       #endregion
      }
      #endregion
     }
     else // 第1列值没变,第2列也没变
      end1++;
    }
 
    // 插入当前数据
    row = sheet.CreateRow(rowIndex);
    #region 创建行并插入当前记录的数据
    //创建行并插入当前记录的数据
    for (int index = 0; index < cellCount; index++)
    {
     ICell cell = row.CreateCell(index);
     string strValue = !(source.Rows[i][cellKeys[index]] is DBNull) ? source.Rows[i][cellKeys[index]].ToString() : string.Empty; // 取值      switch (source.Columns[cellKeys[index]].DataType.ToString())      {       case "System.Int16": //整型       case "System.Int32":       case "System.Int64":       case "System.Byte":        int intV = 0;        int.TryParse(strValue, out intV);        cell.CellStyle = styleNum;        cell.SetCellValue(intV);        break;       case "System.Decimal": //浮点型       case "System.Double":       case "System.Single":        double doubV = 0;        double.TryParse(strValue, out doubV);        cell.CellStyle = styleNum;        cell.SetCellValue(doubV);        break;       default:        cell.CellStyle = styleStr;        cell.SetCellValue(strValue);        break;      }     }     #endregion     // 下移一行     rowIndex++;    }      // 最后一条记录的合计    #region 对第2列进行合并    if (mergeColumns > 1) // 对第2列合并    {     if (start1 != end1) // 开始行和结束行不等,进行合并     {      CellRangeAddress region1 = new CellRangeAddress(start1, end1, 1, 1); // 合并第二列      sheet.AddMergedRegion(region1);     }       #region 第2列加小计     if (isTotal) // 加小计     {      if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移        IRow rowTotal1 = sheet.CreateRow(rowIndex);      //创建列并插入数据      #region 插入小计数据      for (int index = 0; index < cellCount; index++)      {       object obj1;       ICell newcell = rowTotal1.CreateCell(index);       #region 列值处理       if (index == 0) //第1列       {        newcell.CellStyle = styleTotalStr;        newcell.SetCellValue(temp0);        continue;       }       if (index == 1) // 第2列       {        newcell.CellStyle = styleTotalStr;        newcell.SetCellValue("小计");        continue;       }         // 其它列数据,数值进行汇总       switch (source.Columns[cellKeys[index]].DataType.ToString())       {        case "System.Int16": //整型        case "System.Int32":        case "System.Int64":        case "System.Byte":         obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));         int intV = 0;         int.TryParse(obj1.ToString(), out intV);         newcell.CellStyle = styleTotalNum;         newcell.SetCellValue(intV);         break;        case "System.Decimal": //浮点型        case "System.Double":        case "System.Single":         obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' and {2} = '{3}' ", cellKeys[0], temp0, cellKeys[1], temp1));         double doubV = 0;         double.TryParse(obj1.ToString(), out doubV);         newcell.CellStyle = styleTotalNum;         newcell.SetCellValue(doubV);         break;        default:         newcell.CellStyle = styleTotalStr;         newcell.SetCellValue("");         break;       }       #endregion      }      #endregion      // 合并小计      CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 1, 2); // 合并小计      sheet.AddMergedRegion(region0);        rowIndex++;      end0++;     }     #endregion    }    #endregion      #region 对第1列合并    if (mergeColumns > 0) // 对第1列合并    {     if (start0 != end0) // 开始行和结束行不等,进行合并     {      CellRangeAddress region1 = new CellRangeAddress(start0, end0, 0, 0); // 合并第二列      sheet.AddMergedRegion(region1);     }       #region 第1列加合计     if (isTotal) // 加合计     {      if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移        IRow rowTotal0 = sheet.CreateRow(rowIndex);      //创建列并插入数据      #region 插入合计数据      for (int index = 0; index < cellCount; index++)      {       object obj1;       ICell newcell = rowTotal0.CreateCell(index);       #region 列值处理       if (index == 0) //第1列       {        newcell.CellStyle = styleTotalStr;        newcell.SetCellValue("合计");        continue;       }       if (index == 1) // 第2列       {        newcell.CellStyle = styleTotalStr;        newcell.SetCellValue("");        continue;       }         // 其它列数据,数值进行汇总       switch (source.Columns[cellKeys[index]].DataType.ToString())       {        case "System.Int16": //整型        case "System.Int32":        case "System.Int64":        case "System.Byte":         obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' ", cellKeys[0], temp0));         int intV = 0;         newcell.CellStyle = styleTotalNum;         int.TryParse(obj1.ToString(), out intV);         newcell.SetCellValue(intV);         break;        case "System.Decimal": //浮点型        case "System.Double":        case "System.Single":         obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), string.Format("{0} = '{1}' ", cellKeys[0], temp0));         double doubV = 0;         double.TryParse(obj1.ToString(), out doubV);         newcell.CellStyle = styleTotalNum;         newcell.SetCellValue(doubV);         break;        default:         newcell.CellStyle = styleTotalStr;         newcell.SetCellValue("");         break;       }       #endregion      }      #endregion        // 合并合计      CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并合计      sheet.AddMergedRegion(region0);       }     rowIndex++;     #endregion    }    #endregion          #region 进行汇总 - 加总计         if (addAllTotal) // 加总计    {     if (!isConver) sheet.ShiftRows(rowIndex, sheet.LastRowNum, 1, true, false); // 不覆盖,数据向下移       IRow rowTotal0 = sheet.CreateRow(rowIndex);     //创建列并插入数据     #region 插入总计数据     for (int index = 0; index < cellCount; index++)     {      object obj1;      ICell newcell = rowTotal0.CreateCell(index);      #region 列值处理      if (index == 0) //第1列      {       newcell.CellStyle = styleTotalStr;       newcell.SetCellValue("总计");       continue;      }      if (index == 1) // 第2列      {       newcell.CellStyle = styleTotalStr;       newcell.SetCellValue("");       continue;      }        // 其它列数据,数值进行汇总      switch (source.Columns[cellKeys[index]].DataType.ToString())      {       case "System.Int16": //整型       case "System.Int32":       case "System.Int64":       case "System.Byte":        obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), "");        int intV = 0;        int.TryParse(obj1.ToString(), out intV);        newcell.CellStyle = styleTotalNum;        newcell.SetCellValue(intV);        break;       case "System.Decimal": //浮点型       case "System.Double":       case "System.Single":        obj1 = source.Compute(string.Format("sum({0})", cellKeys[index]), "");        double doubV = 0;        double.TryParse(obj1.ToString(), out doubV);        newcell.CellStyle = styleTotalNum;        newcell.SetCellValue(doubV);        break;       default:        newcell.CellStyle = styleTotalStr;        newcell.SetCellValue("");        break;      }      #endregion     }     #endregion       // 合并总计     CellRangeAddress region0 = new CellRangeAddress(rowIndex, rowIndex, 0, 2); // 合并总计     sheet.AddMergedRegion(region0);      }    #endregion     }   return Save2Xls(strFileName, workbook); // 保存为xls文件  }  catch (Exception ex)  {   // FileHelper.WriteLine(logfile, "处理数据异常:" + ex.Message);   // msg = ex.Message;  }  return bn; }

保存文件的代码:

public static bool Save2Xls(string fileName, IWorkbook workbook)
{
 bool bn = false;
 try
 {
  FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate);
 
  MemoryStream ms = new MemoryStream();
  workbook.Write(ms);
  BinaryWriter w = new BinaryWriter(fs);
  w.Write(ms.ToArray());
  fs.Close();
  ms.Close();
 
  bn = true;
 }
 catch(Exception ex)
 {
  //FileHelper.WriteLine(logfile, "保存文件异常:" + ex.Message);
 }
 return bn;
}

上述内容就是怎么在NPOI中实现两级分组合并功能,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注创新互联成都做网站行业资讯频道。

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


网页标题:怎么在NPOI中实现两级分组合并功能-创新互联
网站地址:http://cdkjz.cn/article/dscpeo.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220