Tengo archivos de Excel proporcionados por el usuario que deben convertirse a PDF. Usando excel interop, puedo hacerlo bien con .ExportAsFixedFormat()
. Mi problema surge cuando un libro de trabajo tiene millones de filas. Esto se convierte en un archivo que tiene 50k + páginas. Eso estaría bien si el libro de trabajo tuviera contenido en todas esas filas. Sin embargo, cada vez que aparece uno de estos archivos, hay quizás 50 filas que tienen contenido y el resto están en blanco. ¿Cómo puedo eliminar las filas vacías para poder exportarlas a un PDF de tamaño decente?Eliminar filas vacías con Interop de Excel
He tratado a partir de la fila final y, uno por uno, usando
CountA
para comprobar si la fila tiene contenido y si lo hace, eliminarlo. Esto no solo tarda una eternidad, sino que parece fallar después de unas 100k filas con el siguiente error:No se puede evaluar la expresión porque el código está optimizado o un marco nativo está encima de la pila de llamadas.
He intentado usar
SpecialCells(XlCellType.xlCellTypeLastCell, XlSpecialCellsValue.xlTextValues)
pero eso incluye una fila si alguna celda tiene formato (como un color bg).He intentado usar
Worksheet.UsedRange
y luego eliminar todo después de eso, peroUsedRange
tiene el mismo problema que el punto dos.
Este es el código que he intentado:
for (int i = 0; i < worksheets.Count; i++)
{
sheet = worksheets[i + 1];
rows = sheet.Rows;
currentRowIndex = rows.Count;
bool contentFound = false;
while (!contentFound && currentRowIndex > 0)
{
currentRow = rows[currentRowIndex];
if (Application.WorksheetFunction.CountA(currentRow) == 0)
{
currentRow.Delete();
}
else
{
contentFound = true;
}
Marshal.FinalReleaseComObject(currentRow);
currentRowIndex--;
}
Marshal.FinalReleaseComObject(rows);
Marshal.FinalReleaseComObject(sheet);
}
for (int i = 0; i < worksheets.Count; i++)
{
sheet = worksheets[i + 1];
rows = sheet.Rows;
lastCell = rows.SpecialCells(XlCellType.xlCellTypeLastCell, XlSpecialCellsValue.xlTextValues);
int startRow = lastCell.Row;
Range range = sheet.get_Range(lastCell.get_Address(RowAbsolute: startRow));
range.Delete();
Marshal.FinalReleaseComObject(range);
Marshal.FinalReleaseComObject(lastCell);
Marshal.FinalReleaseComObject(rows);
Marshal.FinalReleaseComObject(sheet);
}
¿Tengo un problema con mi código, ¿es un problema de interoperabilidad o tal vez es sólo una limitación sobre lo que Excel puede hacer? ¿Hay una mejor manera de hacer lo que estoy intentando?
Me gustaría investigar este tema. ¿Tienes un archivo de demostración para hacer pruebas? –
@PilgerstorferFranz Lo siento, no es así. Este proyecto se ha ido. – Chris
¿Encuentra alguna solución? –