diff --git a/cell.go b/cell.go
index f94b81e9d52..8d183b2cc04 100644
--- a/cell.go
+++ b/cell.go
@@ -348,7 +348,7 @@ func (f *File) GetCellFormula(sheet, axis string) (string, error) {
 			return "", false, nil
 		}
 		if c.F.T == STCellFormulaTypeShared {
-			return getSharedForumula(x, c.F.Si), true, nil
+			return getSharedForumula(x, c.F.Si, c.R), true, nil
 		}
 		return c.F.Content, true, nil
 	})
@@ -942,13 +942,108 @@ func isOverlap(rect1, rect2 []int) bool {
 //
 // Note that this function not validate ref tag to check the cell if or not in
 // allow area, and always return origin shared formula.
-func getSharedForumula(ws *xlsxWorksheet, si string) string {
+func getSharedForumula(ws *xlsxWorksheet, si string, axis string) string {
 	for _, r := range ws.SheetData.Row {
 		for _, c := range r.C {
 			if c.F != nil && c.F.Ref != "" && c.F.T == STCellFormulaTypeShared && c.F.Si == si {
-				return c.F.Content
+				var res string
+				col, row, _ := CellNameToCoordinates(axis)
+				sharedCol, sharedRow, _ := CellNameToCoordinates(c.R)
+				dCol := col - sharedCol
+				dRow := row - sharedRow
+				orig := []byte(c.F.Content)
+				var start, end int
+				var stringLiteral bool
+				for end = 0; end < len(orig); end++ {
+					c := orig[end]
+					if c == '"' {
+						stringLiteral = !stringLiteral
+					}
+					if stringLiteral {
+						continue // Skip characters in quotes
+					}
+					if c >= 'A' && c <= 'Z' || c == '$' {
+						res += string(orig[start:end])
+						start = end
+						end++
+						foundNum := false
+						for ; end < len(orig); end++ {
+							idc := orig[end]
+							if idc >= '0' && idc <= '9' || idc == '$' {
+								foundNum = true
+							} else if idc >= 'A' && idc <= 'Z' {
+								if foundNum {
+									break
+								}
+							} else {
+								break
+							}
+						}
+						if foundNum {
+							cellID := string(orig[start:end])
+							res += shiftCell(cellID, dCol, dRow)
+							start = end
+						}
+					}
+				}
+				if start < len(orig) {
+					res += string(orig[start:])
+				}
+				return res
 			}
 		}
 	}
 	return ""
 }
+
+// shiftCell returns the cell shifted according to dCol and dRow taking into consideration of absolute
+// references with dollar sign ($)
+func shiftCell(cellID string, dCol, dRow int) string {
+	fCol, fRow, _ := CellNameToCoordinates2(cellID)
+	signCol, signRow := "", ""
+	if strings.Index(cellID, "$") == 0 {
+		signCol = "$"
+	} else {
+		// Shift column
+		fCol += dCol
+	}
+	if strings.LastIndex(cellID, "$") > 0 {
+		signRow = "$"
+	} else {
+		// Shift row
+		fRow += dRow
+	}
+	colName, _ := ColumnNumberToName(fCol)
+	return signCol + colName + signRow + strconv.Itoa(fRow)
+}
+
+// CellNameToCoordinates2 converts cell name to coordinates taking into consideration of absolute
+// "B3" "$B$3" "B$3" "$B3"  returns 2,3,nil
+func CellNameToCoordinates2(cell string) (col, row int, err error) {
+	wrap := func(err error) (int, int, error) {
+		return -1, -1, fmt.Errorf("CellNameToCoordinates2(%q): %w", cell, err)
+	}
+	var colName = strings.Map(func(rune rune) rune {
+		switch {
+		case 'A' <= rune && rune <= 'Z':
+			return rune
+		case 'a' <= rune && rune <= 'z':
+			return rune - 32
+		}
+		return -1
+	}, cell)
+	row, err = strconv.Atoi(strings.Map(func(rune rune) rune {
+		if rune >= 48 && rune < 58 {
+			return rune
+		}
+		return -1
+	}, cell))
+	if err != nil {
+		return wrap(err)
+	}
+	col, err = ColumnNameToNumber(colName)
+	if err != nil {
+		return wrap(err)
+	}
+	return
+}