India won the toss at Edgbaston and reached 314-9, with opener Rohit Sharma scoring a 92-ball 104, his record-tying fourth century of the tournament. Bangladesh seamer Mustafizur Rahman took 5-59 in Birmingham.
Bangladesh were 286 all out in reply with Shakib Al Hasan again providing the main resistance with a 74-ball 66 including six fours.
Sabbir Rahman (36 in 36 balls) and Mohammad Saifuddin (51 not out off 38 balls) started to hit out and looked dangerous as they took Bangladesh from 179-6 to 245-7, leaving 70 runs required in around seven overs.
The defeat ended any semi-final hopes for seventh-placed Bangladesh, who have seven points from eight games.
India have 13 points, one behind leaders Australia, and play Sri Lanka in their final game at Headingley on Saturday.
Sharma and Lokesh Rahul shared the highest opening stand for this tournament of 180. But Bangladesh struck back to reduce India to 237-4 when Mustafizur's double-wicket maiden claimed Virat Kohli on 26 and Hardik Pandya for a two-ball duck.
Sharma's ton matched Sri Lanka great Kumar Sangakkara's record of centuries at a single World Cup in 2015. After he was out, Rahul went shortly afterward for 77, also in 92 deliveries. Rishabh Pant added a 41-ball 48.
Mustafizur dismissed Mohammed Shami on the last ball of the innings to finish with a five-for. Shakib, the top-ranked ODI all-rounder, took 1-41 in 10 overs and then top-scored in Bangladesh's reply.
Bangladesh had proved they can reel in large totals, pulling off the second highest successful run chase in tournament history (322) to beat the West Indies by seven wickets with eight overs left.
But the Indian bowlers provided tougher opposition and pacer Jasprit Bumrah mopped up with wickets in the 48th and then last over of the match. Bumrah ended on 4-55 and Pandya 3-60.