The 38-year-old Serb took 79 minutes to dispatch the German qualifier and will face either American Sebastian Korda or Italian Lorenzo Musetti, who must win the tournament to secure his place at the season-ending ATP Finals in Turin.
"I think it was the best tennis I've played this tournament," Djokovic added. "It came at the right time. Hanfmann poses a great threat because he serves big, has a big game, so I needed to really stay focused."
Djokovic broke his four-match semi-final losing streak. He had fallen in the last four at Roland Garros, Wimbledon, the US Open and Shanghai.
His last semi-final victory was at the Geneva clay-court event in May when he went on to beat Hubert Hurkacz in the final for his 100th career singles title. The only men with more are Roger Federer (103 titles) and Jimmy Connors (109).
After missing an early opportunity to break the German qualifier at 2-1 in the first set, Djokovic broke at 3-2 and won the set 6-3.
In the second set, Djokovic dropped serve at 2-1, but immediately responded to level the score at 3-3.
Djokovic broke Hanfmann again in the next game and held serve to win before a noisy, supportive crowd at the event which this year took the place of the short-lived Belgrade Open on the ATP schedule.
"Thank you for filling out this amazing stadium again," Djokovic told the fans. "I've played in some of the most beautiful indoor arenas in the world, but I can definitely say this is one of the top three I've ever played in."
