Child shells cannot affect the environment of their parent. If you want the script to affect the parent's environment, you need to:
source ./env.sh
So what's going on? When you run a bash script, either by bash env.sh or env.sh, you're spawning a program with its own environment, an environment that's divorced from its parent. But, when you run the commands contained in the script at the command line, or using source, there is no spawned environment.
Edit to address @syme's comment. Bash scripts meant to be read using source are often pure configuration, containing only assignments and calculations. It's possible to also make them a little more helpful and self-documenting with a clever she-bang hack like:
#!/bin/echo USAGE: source
# Default configuration file for the Frobnicator package.
FOO=bar
BAR=$(stat /baz)
[[ -f /baz ]] && BAZ=file || BAZ=
export FOO BAR BAZ
Making a bash script meant for configuration look like a configuration script, you help future maintainers. You also help yourself my modularizing your script code into distinct parts, each part with its one unique function.
As a side note, please don't export on the same line as you assign.