I hope the following codes could help you. In the side of sample.aspx file:

<asp:GridView ID="GridView1" runat="server"  OnRowCreated = "GridView1_RowCreated"> </asp:GridView>

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.Header)
{
e.Row.Cell[1].Text = "id";
e.Row.Cells[2].Text = "Employee ID";
//You can skip if you made visible="false" for the cell number 3.
e.Row.Cells[4].Text = "KPI Description";
}
}
In the other way, you can try applying looping in this function called GridView1_RowCreated.

protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Cells.Count;i++)
{
if (e.Row.Cells[i].Text == “CORP”)
e.Row.Cells[i].Text = “WinCorp”;
if (e.Row.Cells[i].Text == “PTNR”)
e.Row.Cells[i].Text = “WinPtnr”;
if (e.Row.Cells[i].Text == “SCORP”)
e.Row.Cells[i].Text = “WinScorp”;
if (e.Row.Cells[i].Text == “FIDUC”)
e.Row.Cells[i].Text = “WinFiduc”;
if (e.Row.Cells[i].Text == “WINTAX”)
e.Row.Cells[i].Text = “WinTax”;
if (e.Row.Cells[i].Text == “WINPAY”)
e.Row.Cells[i].Text = “WinPay”;
if (e.Row.Cells[i].Text == “DEPR”)
e.Row.Cells[i].Text = “WinDepr”;
if (e.Row.Cells[i].Text == “CORP”)
e.Row.Cells[i].Text = “WinCorp”;
}
}
 
Reference: http://www.pederborg.dk/2007/01/25/changing-gridview-column-headertext-at-runtime/