11import type {
2+ ExcelCellValue ,
23 MicrosoftExcelReadResponse ,
34 MicrosoftExcelToolParams ,
45} from '@/tools/microsoft_excel/types'
6+ import { trimTrailingEmptyRowsAndColumns } from '@/tools/microsoft_excel/utils'
57import type { ToolConfig } from '@/tools/types'
68
79export const readTool : ToolConfig < MicrosoftExcelToolParams , MicrosoftExcelReadResponse > = {
@@ -75,8 +77,6 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
7577 } ,
7678
7779 transformResponse : async ( response : Response , params ?: MicrosoftExcelToolParams ) => {
78- const defaultAddress = 'A1:Z1000' // Match Google Sheets default logic
79-
8080 // If we came from the worksheets listing (no range provided), resolve first sheet name then fetch range
8181 if ( response . url . includes ( '/workbook/worksheets?' ) ) {
8282 const listData = await response . json ( )
@@ -92,9 +92,10 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
9292 throw new Error ( 'Access token is required to read Excel range' )
9393 }
9494
95+ // Use usedRange(valuesOnly=true) to fetch only populated cells, avoiding thousands of empty rows
9596 const rangeUrl = `https://graph.microsoft.com/v1.0/me/drive/items/${ encodeURIComponent (
9697 spreadsheetIdFromUrl
97- ) } /workbook/worksheets('${ encodeURIComponent ( firstSheetName ) } ')/range(address=' ${ defaultAddress } ' )`
98+ ) } /workbook/worksheets('${ encodeURIComponent ( firstSheetName ) } ')/usedRange(valuesOnly=true )`
9899
99100 const rangeResp = await fetch ( rangeUrl , {
100101 headers : { Authorization : `Bearer ${ accessToken } ` } ,
@@ -109,6 +110,12 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
109110
110111 const data = await rangeResp . json ( )
111112
113+ // usedRange returns an address (A1 notation) and values matrix
114+ const address : string = data . address || data . addressLocal || `${ firstSheetName } !A1`
115+ const rawValues : ExcelCellValue [ ] [ ] = data . values || [ ]
116+
117+ const values = trimTrailingEmptyRowsAndColumns ( rawValues )
118+
112119 const metadata = {
113120 spreadsheetId : spreadsheetIdFromUrl ,
114121 properties : { } ,
@@ -119,8 +126,8 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
119126 success : true ,
120127 output : {
121128 data : {
122- range : data . range || ` ${ firstSheetName } ! ${ defaultAddress } ` ,
123- values : data . values || [ ] ,
129+ range : address ,
130+ values,
124131 } ,
125132 metadata : {
126133 spreadsheetId : metadata . spreadsheetId ,
@@ -144,12 +151,16 @@ export const readTool: ToolConfig<MicrosoftExcelToolParams, MicrosoftExcelReadRe
144151 spreadsheetUrl : `https://graph.microsoft.com/v1.0/me/drive/items/${ spreadsheetId } ` ,
145152 }
146153
154+ const address : string = data . address || data . addressLocal || data . range || ''
155+ const rawValues : ExcelCellValue [ ] [ ] = data . values || [ ]
156+ const values = trimTrailingEmptyRowsAndColumns ( rawValues )
157+
147158 const result : MicrosoftExcelReadResponse = {
148159 success : true ,
149160 output : {
150161 data : {
151- range : data . range || '' ,
152- values : data . values || [ ] ,
162+ range : address ,
163+ values,
153164 } ,
154165 metadata : {
155166 spreadsheetId : metadata . spreadsheetId ,
0 commit comments