
Uma linha entre duas caixas em um fluxograma diz "estas estão relacionadas". Uma seta de uma para a outra diz "esta vem primeiro". Essa distinção — direção — é o que separa um conector de uma decoração, e é justamente o que a API básica Lines.AddLine() não consegue fazer nas duas extremidades. Um fluxo de processo precisa de uma seta saindo de cada etapa; um diagrama de causa e efeito precisa de setas apontando para dentro; uma comparação às vezes precisa de setas de ponta dupla para mostrar um vínculo bidirecional. Nenhum desses casos é possível com um único EndArrowHeadStyle.
O Spire.XLS for JavaScript fornece sheet.TypedLines.AddLine() exatamente para esse caso. Ele posiciona linhas por coordenadas em pixels em vez de linha e coluna, e aceita BeginArrowHeadStyle e EndArrowHeadStyle de forma independente — então uma linha pode ter uma seta em uma extremidade, em ambas ou em nenhuma. O mecanismo é executado no navegador em WebAssembly, com arquivos trafegando por um sistema de arquivos virtual (VFS) e sem envolvimento de backend.
Para a configuração do projeto, consulte Integrando o Spire.XLS for JavaScript em um Projeto React. Os exemplos abaixo pressupõem que o pacote está instalado e que o módulo WebAssembly foi inicializado.
A direção muda tudo
Três diagramas, três requisitos direcionais diferentes, e a mesma API de linha dá conta de todos eles:
| Tipo de diagrama | Configuração de setas | O que comunica |
|---|---|---|
| Fluxo de processo | Seta apenas na extremidade final | Execução sequencial — a etapa A leva à etapa B |
| Cadeia causal | Seta apenas na extremidade final, várias linhas em sequência | A causa produz o efeito, que produz o próximo efeito |
| Vínculo bidirecional | Seta em ambas as extremidades | Relação mútua — A afeta B e B afeta A |
| Indicador de anotação | Seta na extremidade final, sem seta no início | Um rótulo aponta para a célula que descreve |
O estilo da ponta da seta também carrega significado. Uma seta preenchida sólida (LineArrow) é lida como uma conexão definida e comprometida. Uma seta aberta (LineArrowOpen) é lida como uma conexão mais solta e menos certa — comum em diagramas de fluxo de dados, em que a direção é conhecida, mas o mecanismo não é especificado.
Pré-requisitos
Você precisa de um projeto React com o Spire.XLS for JavaScript instalado e o módulo WebAssembly inicializado, acessível em window.wasmModule.spirexls. O exemplo carrega uma fonte no VFS e salva com o sinalizador de versão do Excel 2010.
TypedLines vs Lines: qual é a diferença
sheet.Lines.AddLine() e sheet.TypedLines.AddLine() são duas APIs separadas para duas necessidades separadas. As diferenças são estruturais, não cosméticas:
Lines.AddLine() |
TypedLines.AddLine() |
|
|---|---|---|
| Posicionamento | Coordenadas de linha e coluna | Coordenadas em pixels (Top, Left) |
| Tamanho |
width e height no construtor |
Width e Height como propriedades |
| Seta na extremidade final | EndArrowHeadStyle |
EndArrowHeadStyle |
| Seta no início | Não suportado | BeginArrowHeadStyle |
| Tipo de linha | Definido via lineShapeType no construtor |
Definido pela propriedade LineShapeType
|
| Melhor para | Formas de linha simples alinhadas às células | Conectores direcionais com posicionamento preciso |
O suporte a seta no início é a diferença mais significativa. Com Lines.AddLine(), uma linha pode ter uma ponta de seta na extremidade final, mas não no início — o que é suficiente para um fluxo unidirecional, mas não para um vínculo bidirecional. TypedLines.AddLine() elimina essa restrição.
Para formas de linha básicas sem setas, Inserir Formas de Linha no Excel em JavaScript (React) aborda a API Lines.AddLine().
Posicionamento preciso em pixels
TypedLines.AddLine() posiciona linhas usando Top e Left em pixels, com Width e Height controlando a extensão:
let line = sheet.TypedLines.AddLine();
line.Top = 10; // 10 pixels from the top of the sheet
line.Left = 20; // 20 pixels from the left
line.Width = 100; // 100 pixels wide
line.Height = 0; // 0 height — a horizontal line
Um Height de 0 produz uma linha horizontal; um Width de 0 produz uma linha vertical. Definir ambos com valores diferentes de zero produz uma diagonal ou um conector dobrado, dependendo do LineShapeType.
A mudança de coordenadas de linha e coluna para coordenadas em pixels é mais importante quando as linhas precisam conectar pontos específicos dentro das células — o meio de um intervalo mesclado, a borda de uma borda — em vez de se alinharem aos limites das células. O posicionamento em pixels permite calcular o início e o fim exatos a partir do layout que você conhece, em vez de estimar qual linha e coluna chega mais perto.
Combinações de setas
Com BeginArrowHeadStyle e EndArrowHeadStyle definidos de forma independente, quatro combinações cobrem os casos comuns:
| Início | Fim | Visual | Significado |
|---|---|---|---|
LineNoArrow |
LineArrow |
→ | Direção unidirecional: A leva a B |
LineArrow |
LineArrow |
↔ | Bidirecional: A e B se afetam mutuamente |
LineArrow |
LineNoArrow |
← | Unidirecional reversa: B leva a A (raro, mas útil para layouts da direita para a esquerda) |
LineNoArrow |
LineNoArrow |
— | Sem direção: um conector simples (use Lines.AddLine() em vez disso para simplificar) |
O estilo da seta também pode ser LineArrowOpen — um formato de V aberto em vez de um triângulo preenchido — em qualquer uma das extremidades. Misturar estilos nas duas extremidades é válido: uma seta preenchida em uma extremidade e uma seta aberta na outra comunicam que uma direção é definida e a outra é incerta.
Inserir linhas com setas
O exemplo insere seis linhas com setas em uma nova planilha, cobrindo as combinações comuns: uma linha de seta dupla, uma linha de seta simples, um conector de seta em cotovelo, um conector de seta dupla em cotovelo, um conector de seta curvo e um conector de seta dupla curvo. As etapas são:
- Crie um objeto
Workbooke obtenha a primeira planilha. - Chame
Worksheet.TypedLines.AddLine()para criar cada linha. - Defina a posição da linha por meio de
Top,Left,WidtheHeight(em pixels). - Defina os estilos de seta nas duas extremidades por meio de
BeginArrowHeadStyleeEndArrowHeadStyle. - Especifique o tipo de linha por meio de
LineShapeType(reta, cotovelo, curva, etc.). - Salve a pasta de trabalho com
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 linhas com setas: seta dupla, seta simples, seta em cotovelo, seta dupla em cotovelo, seta curva e seta dupla curva

Observe a reutilização das variáveis line3 e line2 na segunda metade da função. Cada chamada a TypedLines.AddLine() retorna um novo objeto de linha que já foi adicionado à planilha — a variável é um identificador para definir propriedades, não um contêiner que precisa ser preservado. Reutilizar o nome da variável para a próxima linha é seguro porque a linha anterior já está comprometida na coleção de formas da planilha.
Gerenciar linhas existentes
Uma planilha que já contém linhas — sejam adicionadas pelo seu código, importadas de um arquivo ou desenhadas por um usuário — as expõe por meio da coleção sheet.Shapes. Cada forma pode ser recuperada por índice e modificada por meio de suas propriedades:
// 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 exclusão, sheet.Shapes.Remove(index) remove a forma no índice especificado. Para remover linhas seletivamente — por nome, por tipo ou por posição — itere a coleção e remova as formas correspondentes. Remova do último índice para baixo ao excluir em um loop, pois remover um elemento desloca os índices de todos os elementos após ele.
Problemas comuns
A ponta da seta não aparece.
BeginArrowHeadStyle ou EndArrowHeadStyle não foi definido, ou foi definido como LineNoArrow. Verifique em qual extremidade você espera a seta e atribua a propriedade correspondente. Uma linha sem nenhuma das duas propriedades definidas não tem setas em nenhuma extremidade.
A linha aparece na posição errada.
Top e Left estão em pixels, não em linhas e colunas. Um valor de Top = 10 coloca a linha a 10 pixels do topo da planilha, não na linha 10. Se você está acostumado com a API Lines.AddLine(), esta é a fonte mais comum de posicionamento incorreto.
O conector em cotovelo dobra na direção errada.
A direção da dobra depende dos sinais e das magnitudes relativas de Width e Height. Um Width positivo com um Height positivo dobra para baixo e para a direita. Inverta o sinal ou troque os dois valores para mudar a dobra. Teste com valores pequenos primeiro.
A linha curva não curva como eu esperava.
Uma CurveLine por meio de TypedLines desenha um arco suave entre os pontos inicial e final, e a forma do arco é influenciada por Width e Height. Ao contrário de um conector em cotovelo, que tem uma única dobra em ângulo reto, uma curva é contínua — mas seu caminho exato depende das dimensões, então verifique a saída antes de confiar nela para um layout preciso.
Perguntas frequentes
Qual é a diferença entre LineArrow e LineArrowOpen?
LineArrow desenha uma ponta de seta triangular preenchida. LineArrowOpen desenha uma ponta de seta aberta em forma de V — dois traços sem preenchimento. O estilo aberto é comum em diagramas de fluxo de dados e de entidade-relacionamento, em que a seta indica direção sem implicar um mecanismo específico.
Posso definir estilos de seta diferentes nas duas extremidades?
Sim. BeginArrowHeadStyle e EndArrowHeadStyle são propriedades independentes. Uma linha com LineArrow em uma extremidade e LineArrowOpen na outra é válida e comunica que uma direção é definida enquanto a outra é incerta.
Como as coordenadas em pixels se relacionam com o layout da planilha?
As coordenadas em pixels são medidas a partir do canto superior esquerdo da planilha. As alturas das linhas e as larguras das colunas no Excel são medidas em pontos e caracteres, respectivamente, portanto converter entre posições de células e coordenadas em pixels exige considerar as alturas de linha e larguras de coluna atuais. Para linhas que precisam se alinhar aos limites das células, Lines.AddLine() com parâmetros de linha e coluna pode ser mais simples.
Posso misturar Lines.AddLine() e TypedLines.AddLine() na mesma planilha?
Sim. As duas APIs adicionam formas à mesma coleção de formas da planilha. Uma planilha pode conter formas de linha básicas e linhas com setas simultaneamente.
Isso exige que o Excel esteja instalado?
Não. O mecanismo é executado como WebAssembly no navegador. As linhas e setas são gravadas como objetos de forma padrão no XML da planilha, e o Excel as renderiza nativamente quando o arquivo é aberto.