In QGIS I can suggest using a "Virtual Layer" through Layer > Add Layer > Add/Edit Virtual Layer...
.
Let's assume there is a layer 'layer_with_holes' with its corresponding attribute table, see image below.

There are possible two cases.
Case I. When holes that are located on the polygon edges should not be included.
With the following query, it is possible to create a new polygon layer from the empty gaps inside the polygons.
-- generate series
WITH RECURSIVE generate_series(cat) AS (
SELECT conf.start
FROM conf
UNION ALL
SELECT cat + conf.step
FROM generate_series, conf
WHERE cat + conf.step <= conf.stop
),
-- config
conf AS (
SELECT
1 AS start,
1 AS step,
SUM(st_numgeometries(st_difference(make_polygon(st_exteriorring(l.geometry)), l.geometry))) AS stop
FROM "layer_with_holes" AS l
)
-- query
SELECT cat, st_geometryn(st_union(st_difference(make_polygon(st_exteriorring(l.geometry)), l.geometry)), cat) AS geom
FROM generate_series, "layer_with_holes" AS l
GROUP BY cat
The output Virtual Layer with its Attribute table will look as follows.

Case II. When holes that are located on the polygon edges should be included.
With the following query, it is possible to create a new polygon layer from the empty gaps within the polygons.
-- generate series
WITH RECURSIVE generate_series(cat) AS (
SELECT conf.start
FROM conf
UNION ALL
SELECT cat + conf.step
FROM generate_series, conf
WHERE cat + conf.step <= conf.stop
),
-- config
conf AS (
SELECT
1 AS start,
1 AS step,
SUM(st_numgeometries(st_difference(make_polygon(st_exteriorring(l.geometry)), l.geometry))) + st_numgeometries(st_difference(make_polygon(st_exteriorring(st_union(make_polygon(st_exteriorring(l.geometry))))), st_union(make_polygon(st_exteriorring(l.geometry))))) AS stop
FROM "layer_with_holes" AS l
)
-- query
SELECT cat, st_geometryn((st_union(st_union(st_difference(make_polygon(st_exteriorring(l.geometry)), l.geometry)), st_difference(make_polygon(st_exteriorring(st_union(make_polygon(st_exteriorring(l.geometry))))), st_union(make_polygon(st_exteriorring(l.geometry))))), cat) AS geom
FROM generate_series, "layer_with_holes" AS l
GROUP BY cat
The output Virtual Layer with its Attribute table will look as follows.
