How to URL-Encode and Decode Text in Google Sheets and Excel

Updated

To URL-encode in a spreadsheet, use =ENCODEURL(A2), which exists in Google Sheets and in Excel 2016 or later on Windows. Neither app has a built-in URL decode function, so decoding needs either a short custom function (Apps Script in Sheets, VBA in Excel) or a SUBSTITUTE chain for a few known codes.

This guide gives copy-ready versions of each, plus the mistakes that most often break spreadsheet-built URLs.

URL encode and decode in Google Sheets and Excel Encoding: ENCODEURL works in Google Sheets and in Excel 2016 or later on Windows, but not in Excel for Mac or the web. Decoding: no built-in function anywhere; use an Apps Script custom function in Sheets, a VBA function in desktop Excel, or a SUBSTITUTE chain for a few ASCII codes. URL encode and decode in spreadsheets Google Sheets Excel (Windows) Excel Mac / web Encode =ENCODEURL(A2) =ENCODEURL(A2) not available Decode Apps Script =URL_DECODE(A2) VBA macro =URL_DECODE(A2) VBA on Mac desktop; SUBSTITUTE on web Rules that prevent broken URLs 1. Encode values only: ="https://example.com/?q=" & ENCODEURL(A2) 2. Never encode a column twice (%20 → %2520) 3. SUBSTITUTE chains: replace %25 last; ASCII codes only
Which URL encode and decode options exist in Google Sheets and Excel

What each app supports

Task Google Sheets Excel (Windows, 2016+ / Microsoft 365) Excel for Mac / web
Encode ENCODEURL ENCODEURL Not available (Microsoft)
Decode Apps Script custom function VBA function Not built in; use the SUBSTITUTE method
Simple decode of a few codes SUBSTITUTE chain SUBSTITUTE chain SUBSTITUTE chain

Microsoft's ENCODEURL page lists support in Excel for Microsoft 365, 2024, 2021, 2019 and 2016, and says the function is not available in Excel for the web or Excel for Mac.

Encoding with ENCODEURL

ENCODEURL takes one text argument and returns it percent-encoded, with spaces as %20. Google's help page shows =ENCODEURL("hello, world!") returning hello%2C%20world%21, and describes the function as encoding text for use in the query string of a URL. Microsoft's own example shows how much it encodes:

=ENCODEURL("http://contoso.sharepoint.com/Finance/Profit and Loss Statement.xlsx")
→ http%3A%2F%2Fcontoso.sharepoint.com%2FFinance%2FProfit%20and%20Loss%20Statement.xlsx

Because it encodes : and /, apply it to values only, never to a finished URL.

Building a search or campaign URL

With a keyword in A2:

="https://example.com/search?q=" & ENCODEURL(A2)

With UTM values in B2:D2 (source, medium, campaign):

="https://example.com/landing?utm_source=" & ENCODEURL(B2)
  & "&utm_medium=" & ENCODEURL(C2)
  & "&utm_campaign=" & ENCODEURL(D2)

A campaign name such as spring sale becomes spring%20sale. For naming rules that avoid encoding altogether, see UTM parameter encoding mistakes.

Check before you encode

If a column already contains encoded text, running ENCODEURL again turns %20 into %2520. A quick test column flags those rows:

=REGEXMATCH(A2, "%[0-9A-Fa-f]{2}")      (Google Sheets)
=ISNUMBER(SEARCH("%2", A2))             (rough check in Excel)

The Excel version only catches codes that start with %2 (space, &, /, + and so on), which covers the common cases. Double URL encoding (%2520) explains how to clean up rows that were encoded twice.

Decoding in Google Sheets with Apps Script

Google's Apps Script guide explains how to add a custom function: open Extensions > Apps Script, paste the code, save, and call it from a cell like a built-in function. This one decodes single cells or whole ranges:

/**
 * Decodes URL-encoded (percent-encoded) text.
 * @param {string|Array<Array<string>>} input Text or range to decode.
 * @param {boolean} plusAsSpace Treat + as a space (default TRUE).
 * @return The decoded text.
 * @customfunction
 */
function URL_DECODE(input, plusAsSpace) {
  if (Array.isArray(input)) return input.map(row => row.map(v => URL_DECODE(v, plusAsSpace)));
  if (input === "" || input === null) return "";
  let s = String(input);
  if (plusAsSpace !== false) s = s.replace(/\+/g, " ");
  try { return decodeURIComponent(s); } catch (e) { return "#MALFORMED: " + String(input); }
}

Use it as =URL_DECODE(A2) or =URL_DECODE(A2:A500). Results from a test run of the same code:

Input =URL_DECODE(A2) =URL_DECODE(A2, FALSE)
caf%C3%A9+au+lait café au lait café+au+lait
spring%20sale spring sale spring sale
%E2%82%AC5 €5 €5
100% #MALFORMED: 100% #MALFORMED: 100%

Notes from Google's documentation: a custom function must finish within 30 seconds, and each call is a separate server request, so one call on a range is faster than thousands of single-cell calls. The + option exists because form-encoded query strings use + for spaces; see %20 vs + in URLs.

Decoding in Excel with VBA

Excel has no decode counterpart to ENCODEURL. On Windows or Mac desktop Excel you can add a VBA function: press Alt+F11, choose Insert > Module, paste the code and save the workbook as .xlsm.

Public Function URL_DECODE(ByVal s As String, Optional ByVal plusAsSpace As Boolean = True) As String
    Dim i As Long, cnt As Long, h As String, out As String
    Dim buf() As Byte
    If plusAsSpace Then s = Replace(s, "+", " ")
    ReDim buf(0 To Len(s))
    i = 1
    Do While i <= Len(s)
        h = Mid$(s, i + 1, 2)
        If Mid$(s, i, 1) = "%" And Len(h) = 2 And h Like "[0-9A-Fa-f][0-9A-Fa-f]" Then
            buf(cnt) = CByte("&H" & h): cnt = cnt + 1
            i = i + 3
        Else
            If cnt > 0 Then out = out & Utf8ToString(buf, cnt): cnt = 0
            out = out & Mid$(s, i, 1)
            i = i + 1
        End If
    Loop
    If cnt > 0 Then out = out & Utf8ToString(buf, cnt)
    URL_DECODE = out
End Function

Private Function Utf8ToString(b() As Byte, ByVal n As Long) As String
    Dim i As Long, k As Long, extra As Long, cp As Long, ok As Boolean, out As String
    Do While i < n
        If b(i) < &H80 Then
            cp = b(i): extra = 0
        ElseIf b(i) >= &HC0 And b(i) < &HE0 Then
            cp = b(i) And &H1F: extra = 1
        ElseIf b(i) >= &HE0 And b(i) < &HF0 Then
            cp = b(i) And &HF: extra = 2
        ElseIf b(i) >= &HF0 And b(i) < &HF8 Then
            cp = b(i) And &H7: extra = 3
        Else
            extra = -1
        End If
        ok = (extra >= 0 And i + extra <= n - 1)
        If ok Then
            For k = 1 To extra
                If (b(i + k) And &HC0) <> &H80 Then ok = False
            Next k
        End If
        If Not ok Then
            out = out & ChrW(&HFFFD&): i = i + 1
        Else
            For k = 1 To extra
                cp = cp * 64 + (b(i + k) And &H3F)
            Next k
            i = i + extra + 1
            If cp > &HFFFF& Then
                cp = cp - &H10000
                out = out & ChrW(&HD800& + cp \ 1024) & ChrW(&HDC00& + (cp And &H3FF&))
            Else
                out = out & ChrW(cp)
            End If
        End If
    Loop
    Utf8ToString = out
End Function

It collects runs of %XX bytes and converts them as UTF-8, so caf%C3%A9 gives café and %F0%9F%98%80 gives 😀. Invalid sequences such as a lone %C3 become the replacement character �, and a % that is not followed by two hex digits is kept as is. We tested the algorithm with a line-by-line port in Python against the examples above; test the macro on a copy of your data before relying on it.

The no-code option: SUBSTITUTE

For ASCII text with a handful of known codes, nested SUBSTITUTE calls work in both apps and in Excel for the web:

=SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A2,
  "%20"," "), "%2F","/"), "%3A",":"), "%26","&"), "%25","%")

Three rules keep it correct:

  1. Replace %25 last. Otherwise %2520 turns into %20 and then into a space, which decodes twice.
  2. Add lowercase variants if needed. SUBSTITUTE is case-sensitive, and RFC 3986 allows %2f as well as %2F, although it recommends uppercase.
  3. Do not use it for non-ASCII text. Characters such as é are several bytes (%C3%A9) and need a real UTF-8 decoder.

Common spreadsheet mistakes

  • Encoding the whole URL instead of the values.
  • Encoding a column twice, producing %2520.
  • Copying URLs from an HTML export, which may contain &amp; instead of &.
  • Trailing spaces in cells, which become %20 at the end of a parameter. Wrap inputs in TRIM().
  • Mixed case in UTM values. Google Analytics 4 treats Email and email as different values; use LOWER() before encoding.

To check a finished URL from your sheet, paste it into the URL parser, which lists every parameter decoded and flags double encoding. For one-off strings, the URL encode and decode operations on the universal encoder decoder give the same result as the formulas above.

Frequently asked questions

Is there a URL decode function in Google Sheets?

No built-in one. Google Sheets has ENCODEURL for encoding, but decoding needs a custom function written in Apps Script, such as the URL_DECODE function in this guide, or a chain of SUBSTITUTE calls for a few known codes.

Why does ENCODEURL not work in Excel for Mac or Excel for the web?

Microsoft's documentation says ENCODEURL is not available in Excel for the web, and that on Mac it may appear in the function list but relies on Windows operating system features and will not return results. It is supported in Excel 2016 and later and Microsoft 365 on Windows.

Should I run ENCODEURL on a whole URL?

No. It encodes the colon and slashes too, so https://example.com becomes https%3A%2F%2Fexample.com. Encode only the parameter values and join them to the fixed part of the URL with &.

Split a URL into scheme, host, path, query and fragment, and decode every parameter.

Open the URL Parser

Sources