
Una línea entre dos cuadros en un diagrama de flujo dice "estos están relacionados". Una flecha de uno hacia el otro dice "este va primero". Esa distinción — la dirección — es lo que separa un conector de una decoración, y es lo único que la API básica Lines.AddLine() no puede hacer en ambos extremos. Un flujo de proceso necesita una flecha que salga de cada paso; un diagrama de causa y efecto necesita flechas que apunten hacia dentro; una comparación a veces necesita flechas de doble punta para mostrar un vínculo bidireccional. Nada de esto es posible con un único EndArrowHeadStyle.
Spire.XLS for JavaScript proporciona sheet.TypedLines.AddLine() precisamente para este caso. Posiciona las líneas mediante coordenadas en píxeles en lugar de filas y columnas, y acepta BeginArrowHeadStyle y EndArrowHeadStyle de forma independiente, de modo que una línea puede llevar una flecha en un extremo, en ambos extremos o en ninguno. El motor se ejecuta en el navegador sobre WebAssembly, con los archivos moviéndose a través de un sistema de archivos virtual (VFS) y sin ningún backend implicado.
Para la configuración del proyecto, consulte Integrating Spire.XLS for JavaScript in a React Project. Los ejemplos a continuación asumen que el paquete está instalado y que el módulo WebAssembly se ha inicializado.
La dirección lo cambia todo
Tres diagramas, tres requisitos direccionales diferentes, y la misma API de líneas los gestiona todos:
| Tipo de diagrama | Configuración de flechas | Qué comunica |
|---|---|---|
| Flujo de proceso | Flecha solo en el final | Ejecución secuencial: el paso A lleva al paso B |
| Cadena causal | Flecha solo en el final, varias líneas en secuencia | La causa produce un efecto, que produce el siguiente efecto |
| Vínculo bidireccional | Flecha en ambos extremos | Relación mutua: A afecta a B y B afecta a A |
| Puntero de anotación | Flecha en el final, sin flecha en el inicio | Una etiqueta apunta a la celda que describe |
El propio estilo de la punta de flecha también transmite significado. Una flecha rellena sólida (LineArrow) se interpreta como una conexión definida y comprometida. Una flecha abierta (LineArrowOpen) se interpreta como una más flexible y menos segura, común en diagramas de flujo de datos donde la dirección se conoce pero el mecanismo no está especificado.
Requisitos previos
Necesita un proyecto de React con Spire.XLS for JavaScript instalado y el módulo WebAssembly inicializado, accesible en window.wasmModule.spirexls. El ejemplo carga una fuente en el VFS y guarda con la marca de versión de Excel 2010.
TypedLines vs Lines: en qué se diferencian
sheet.Lines.AddLine() y sheet.TypedLines.AddLine() son dos API separadas para dos necesidades distintas. Las diferencias son estructurales, no cosméticas:
Lines.AddLine() |
TypedLines.AddLine() |
|
|---|---|---|
| Posicionamiento | Coordenadas de fila y columna | Coordenadas en píxeles (Top, Left) |
| Tamaño |
width y height en el constructor |
Width y Height como propiedades |
| Flecha en el final | EndArrowHeadStyle |
EndArrowHeadStyle |
| Flecha en el inicio | No compatible | BeginArrowHeadStyle |
| Tipo de línea | Se establece mediante lineShapeType en el constructor |
Se establece mediante la propiedad LineShapeType
|
| Ideal para | Formas de línea simples alineadas con celdas | Conectores direccionales con colocación precisa |
La compatibilidad con flechas en el inicio es la diferencia más trascendental. Con Lines.AddLine(), una línea puede tener una punta de flecha en su final pero no en su inicio, lo cual es suficiente para un flujo unidireccional pero no para un vínculo bidireccional. TypedLines.AddLine() elimina esa restricción.
Para formas de línea básicas sin flechas, Insert Line Shapes in Excel in JavaScript (React) cubre la API Lines.AddLine().
Posicionamiento preciso al píxel
TypedLines.AddLine() coloca las líneas usando Top y Left en píxeles, con Width y Height controlando la extensión:
let line = sheet.TypedLines.AddLine();
line.Top = 10; // 10 píxeles desde la parte superior de la hoja
line.Left = 20; // 20 píxeles desde la izquierda
line.Width = 100; // 100 píxeles de ancho
line.Height = 0; // altura 0 — una línea horizontal
Un Height de 0 produce una línea horizontal; un Width de 0 produce una vertical. Establecer ambos en valores distintos de cero produce una diagonal o un conector acodado, según el LineShapeType.
El cambio de coordenadas de fila y columna a píxeles importa sobre todo cuando las líneas necesitan conectar puntos específicos dentro de las celdas — el centro de un rango combinado, el borde de un borde de celda — en lugar de alinearse con los límites de las celdas. El posicionamiento en píxeles le permite calcular el inicio y el final exactos a partir del diseño que conoce, en lugar de estimar qué fila y columna queda más cerca.
Combinaciones de flechas
Con BeginArrowHeadStyle y EndArrowHeadStyle establecidos de forma independiente, cuatro combinaciones cubren los casos comunes:
| Inicio | Final | Visual | Significado |
|---|---|---|---|
LineNoArrow |
LineArrow |
→ | Dirección unidireccional: A lleva a B |
LineArrow |
LineArrow |
↔ | Bidireccional: A y B se afectan mutuamente |
LineArrow |
LineNoArrow |
← | Unidireccional inversa: B lleva a A (poco común, pero útil para diseños de derecha a izquierda) |
LineNoArrow |
LineNoArrow |
— | Sin dirección: un conector simple (use Lines.AddLine() en su lugar por simplicidad) |
El estilo de flecha también puede ser LineArrowOpen — una forma de V abierta en lugar de un triángulo relleno — en cualquiera de los extremos. Mezclar estilos en los dos extremos es válido: una flecha rellena en un extremo y una flecha abierta en el otro comunica que una dirección es definida y la otra es tentativa.
Insertar líneas con punta de flecha
El ejemplo inserta seis líneas con punta de flecha en una hoja de cálculo nueva, cubriendo las combinaciones comunes: una línea de doble flecha, una línea de flecha simple, un conector de flecha acodado, un conector acodado de doble flecha, un conector de flecha curvo y un conector curvo de doble flecha. Los pasos son:
- Crear un objeto
Workbooky obtener la primera hoja de cálculo. - Llamar a
Worksheet.TypedLines.AddLine()para crear cada línea. - Establecer la posición de la línea mediante
Top,Left,WidthyHeight(en píxeles). - Establecer los estilos de flecha en ambos extremos mediante
BeginArrowHeadStyleyEndArrowHeadStyle. - Especificar el tipo de línea mediante
LineShapeType(recta, acodada, curva, etc.). - Guardar el libro con
Workbook.SaveToFile().
function App() {
const addArrowLines = async () => {
// Get the Spire.XLS WASM module
const xlsModule = window.wasmModule?.spirexls;
// Check whether the module is ready
if (!xlsModule) {
alert('Spire.Xls is not ready yet');
return;
}
// Load the font into the VFS for text measurement and column auto-fit
await window.spire.FetchFileToVFS('ARIAL.TTF', '/Library/Fonts/', `${process.env.PUBLIC_URL}/font/`);
// Create a new workbook and get the first worksheet
const workbook = new xlsModule.Workbook();
const sheet = workbook.Worksheets.get(0);
// Add a double-arrow line - solid blue
let line = sheet.TypedLines.AddLine();
line.Top = 10;
line.Left = 20;
line.Width = 100;
line.Height = 0;
line.Color = xlsModule.Color.get_Blue();
line.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
// Add a single-arrow line - solid red
let line_1 = sheet.TypedLines.AddLine();
line_1.Top = 50;
line_1.Left = 30;
line_1.Width = 100;
line_1.Height = 100;
line_1.Color = xlsModule.Color.get_Red();
line_1.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineNoArrow;
line_1.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
// Add an elbow arrow connector
let line3 = sheet.TypedLines.AddLine();
line3.LineShapeType = xlsModule.LineShapeType.ElbowLine;
line3.Width = 30;
line3.Height = 50;
line3.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line3.Top = 100;
line3.Left = 50;
// Add an elbow double-arrow connector
let line2 = sheet.TypedLines.AddLine();
line2.LineShapeType = xlsModule.LineShapeType.ElbowLine;
line2.Width = 50;
line2.Height = 50;
line2.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line2.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrow;
line2.Left = 120;
line2.Top = 100;
// Add a curved arrow connector
line3 = sheet.TypedLines.AddLine();
line3.LineShapeType = xlsModule.LineShapeType.CurveLine;
line3.Width = 30;
line3.Height = 50;
line3.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line3.Top = 100;
line3.Left = 200;
// Add a curved double-arrow connector
line2 = sheet.TypedLines.AddLine();
line2.LineShapeType = xlsModule.LineShapeType.CurveLine;
line2.Width = 30;
line2.Height = 50;
line2.EndArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line2.BeginArrowHeadStyle = xlsModule.ShapeArrowStyleType.LineArrowOpen;
line2.Left = 250;
line2.Top = 100;
// Save the workbook
const outputFileName = 'AddArrowLines.xlsx';
workbook.SaveToFile({ fileName: outputFileName, version: xlsModule.ExcelVersion.Version2010 });
// Release resources
workbook.Dispose();
// Read the saved file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(outputFileName);
const blob = new Blob([fileArray], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = outputFileName;
a.click();
URL.revokeObjectURL(url);
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Add Arrow Lines</h1>
<button onClick={addArrowLines}>Start</button>
</div>
);
}
export default App;
Seis líneas con punta de flecha: doble flecha, flecha simple, flecha acodada, doble flecha acodada, flecha curva y doble flecha curva

Observe la reutilización de las variables line3 y line2 en la segunda mitad de la función. Cada llamada a TypedLines.AddLine() devuelve un nuevo objeto de línea que ya se ha añadido a la hoja de cálculo: la variable es un identificador para establecer propiedades, no un contenedor que deba conservarse. Reutilizar el nombre de la variable para la siguiente línea es seguro porque la línea anterior ya está confirmada en la colección de formas de la hoja.
Gestionar líneas existentes
Una hoja de cálculo que ya contiene líneas — ya sea añadidas por su código, importadas desde un archivo o dibujadas por un usuario — las expone a través de la colección sheet.Shapes. Cada forma se puede recuperar por índice y modificar a través de sus propiedades:
// Get the first shape in the worksheet
let shape = sheet.Shapes.get(0);
// Modify its properties — color, dash style, etc.
shape.Color = xlsModule.Color.get_Red();
Para la eliminación, sheet.Shapes.Remove(index) elimina la forma en el índice especificado. Para eliminar líneas de forma selectiva — por nombre, por tipo o por posición — recorra la colección y elimine las formas que coincidan. Elimine desde el último índice hacia abajo cuando elimine en un bucle, ya que al eliminar un elemento se desplazan los índices de todos los elementos posteriores.
Problemas comunes
La punta de flecha no aparece.
No se estableció BeginArrowHeadStyle o EndArrowHeadStyle, o se estableció en LineNoArrow. Compruebe en qué extremo espera la flecha y asigne la propiedad correspondiente. Una línea sin ninguna de las dos propiedades establecidas no tiene flechas en ninguno de los extremos.
La línea aparece en la posición equivocada.
Top y Left están en píxeles, no en filas y columnas. Un valor de Top = 10 coloca la línea a 10 píxeles de la parte superior de la hoja, no en la fila 10. Si está acostumbrado a la API Lines.AddLine(), esta es la causa más común de mala colocación.
El conector acodado se dobla en la dirección equivocada.
La dirección del doblez depende de los signos y las magnitudes relativas de Width y Height. Un Width positivo con un Height positivo se dobla hacia abajo a la derecha. Cambie el signo o intercambie los dos valores para cambiar el doblez. Pruebe primero con valores pequeños.
La línea curva no se curva como esperaba.
Una CurveLine a través de TypedLines dibuja un arco suave entre los puntos de inicio y fin, y la forma del arco se ve influida por Width y Height. A diferencia de un conector acodado, que tiene un único doblez en ángulo recto, una curva es continua, pero su trayectoria exacta depende de las dimensiones, así que verifique el resultado antes de confiar en ella para un diseño preciso.
Preguntas frecuentes
¿Cuál es la diferencia entre LineArrow y LineArrowOpen?
LineArrow dibuja una punta de flecha triangular rellena. LineArrowOpen dibuja una punta de flecha abierta en forma de V: dos trazos sin relleno. El estilo abierto es común en diagramas de flujo de datos y de entidad-relación, donde la flecha indica la dirección sin implicar un mecanismo específico.
¿Puedo establecer estilos de flecha diferentes en los dos extremos?
Sí. BeginArrowHeadStyle y EndArrowHeadStyle son propiedades independientes. Una línea con LineArrow en un extremo y LineArrowOpen en el otro es válida y comunica que una dirección es definida mientras que la otra es tentativa.
¿Cómo se relacionan las coordenadas en píxeles con el diseño de la hoja de cálculo?
Las coordenadas en píxeles se miden desde la esquina superior izquierda de la hoja de cálculo. Las alturas de fila y los anchos de columna en Excel se miden en puntos y caracteres respectivamente, por lo que convertir entre posiciones de celdas y coordenadas en píxeles requiere tener en cuenta las alturas de fila y los anchos de columna actuales. Para líneas que necesitan alinearse con los límites de las celdas, Lines.AddLine() con parámetros de fila y columna puede ser más sencillo.
¿Puedo mezclar Lines.AddLine() y TypedLines.AddLine() en la misma hoja de cálculo?
Sí. Ambas API añaden formas a la misma colección de formas de la hoja de cálculo. Una hoja de cálculo puede contener formas de línea básicas y líneas con punta de flecha simultáneamente.
¿Esto requiere que Excel esté instalado?
No. El motor se ejecuta como WebAssembly en el navegador. Las líneas y flechas se escriben como objetos de forma estándar en el XML de la hoja de cálculo, y Excel las representa de forma nativa cuando se abre el archivo.