Como usar "xlBookLoad" Excel com LibXL
Enviado: 05 Mai 2025 09:56
Olá!
Usando o xHarbour 123/BCC7.3, estou fazendo uns testes com a DLL LibXL.dll, abrindo-a com um LoadLibrary( "libxl.dll" ) e fiz uma Classe para chamar suas funções e processa-las na minha aplicação.
Acontece que não consegue abrir uma planilha já existente, para q eu possa implementar valores nas células. E a falha acho que está ao passar a String com o nome da planilha.
Segue os fontes abaixo para a ajuda dos amigos.
Como usar:
Fico grato pela ajuda.
Usando o xHarbour 123/BCC7.3, estou fazendo uns testes com a DLL LibXL.dll, abrindo-a com um LoadLibrary( "libxl.dll" ) e fiz uma Classe para chamar suas funções e processa-las na minha aplicação.
Acontece que não consegue abrir uma planilha já existente, para q eu possa implementar valores nas células. E a falha acho que está ao passar a String com o nome da planilha.
Segue os fontes abaixo para a ajuda dos amigos.
Código: Selecionar todos
#pragma -w0
#pragma -es0
#include "hbclass.ch"
#Define DC_CALL_STD 0x0020
CREATE CLASS XLExcel
VAR hDll
VAR Book
VAR Sheet
VAR cFileName
METHOD New()
METHOD End()
METHOD CreateBook( lXlsx )
METHOD LoadBook( cFile )
METHOD AddSheet( cSheet )
METHOD GetSheet( nIndex )
METHOD WriteStr( nRow, nCol, cText )
METHOD WriteNum( nRow, nCol, nNum )
METHOD ReadStr( nRow, nCol )
METHOD ReadNum( nRow, nCol )
METHOD SaveBook( cFile )
METHOD Save()
METHOD CloseBook()
METHOD ErrorMsg()
ENDCLASS
//--------------------------------------------------------------------
METHOD New() CLASS XLExcel
::hDll := LoadLibrary( "libxl.dll" )
RETURN Self
METHOD End() CLASS XLExcel
IF !Empty(::hDll)
FreeLibrary( ::hDll )
ENDIF
RETURN NIL
METHOD CreateBook( lXlsx ) CLASS XLExcel
DEFAULT( @lXlsx, .T.)
::Book := If( lXlsx, ;
CallDllStd(::hDll, "xlCreateXMLBook"), ;
CallDllStd(::hDll, "xlCreateBook") )
::cFileName := NIL
RETURN ::Book
METHOD LoadBook( cFile ) CLASS XLExcel
LOCAL cExt, cFileW
cExt := Lower( Right( cFile, 5 ) )
IF ".xlsx" $ cExt
::Book := CallDllStd(::hDll, "xlCreateXMLBook")
ELSE
::Book := CallDllStd(::hDll, "xlCreateBook")
ENDIF
cFileW := CHAR_TO_WCHAR(hb_strToUTF8(cFile))
IF CallDllStd(::hDll, "xlBookLoad", ::Book, cFileW) == 1
::cFileName := cFile
RETURN .T.
ENDIF
RETURN .t.
METHOD AddSheet( cSheet ) CLASS XLExcel
::Sheet := CallDllStd(::hDll, "xlBookAddSheet", ::Book, hb_strToUTF8(cSheet), 0)
RETURN ::Sheet
METHOD GetSheet( nIndex ) CLASS XLExcel
::Sheet := CallDllStd(::hDll, "xlBookGetSheet", ::Book, nIndex)
RETURN ::Sheet
METHOD WriteStr( nRow, nCol, cText ) CLASS XLExcel
IF !Empty(::Sheet)
RETURN CallDllStd(::hDll, "xlSheetWriteStr", ::Sheet, nRow, nCol, hb_strToUTF8(cText), 0)
ENDIF
RETURN 0
METHOD WriteNum( nRow, nCol, nNum ) CLASS XLExcel
IF !Empty(::Sheet)
RETURN CallDllStd(::hDll, "xlSheetWriteNum", ::Sheet, nRow, nCol, nNum, 0)
ENDIF
RETURN 0
METHOD ReadStr( nRow, nCol ) CLASS XLExcel
IF !Empty(::Sheet)
RETURN CallDllStd(::hDll, "xlSheetReadStr", ::Sheet, nRow, nCol)
ENDIF
RETURN ""
METHOD ReadNum( nRow, nCol ) CLASS XLExcel
IF !Empty(::Sheet)
RETURN CallDllStd(::hDll, "xlSheetReadNum", ::Sheet, nRow, nCol)
ENDIF
RETURN 0
METHOD SaveBook( cFile ) CLASS XLExcel
::cFileName := cFile
RETURN CallDllStd(::hDll, "xlBookSave", ::Book, hb_strToUTF8(cFile)) == 1
METHOD Save() CLASS XLExcel
IF Empty(::cFileName)
RETURN .F.
ENDIF
RETURN CallDllStd(::hDll, "xlBookSave", ::Book, hb_strToUTF8(::cFileName)) == 1
METHOD CloseBook() CLASS XLExcel
IF !Empty(::Book)
CallDllStd(::hDll, "xlBookRelease", ::Book)
::Book := NIL
::Sheet := NIL
::cFileName := NIL
ENDIF
RETURN NIL
METHOD ErrorMsg() CLASS XLExcel
LOCAL pStr := CallDllStd(::hDll, "xlBookErrorMessage", ::Book)
RETURN PtrToStr(pStr)
STATIC FUNCTION CallDllStd( hLib, cFunc, a1, a2, a3, a4, a5, a6, a7 )
RETURN DllCall( hLib, DC_CALL_STD, cFunc, a1, a2, a3, a4, a5, a6, a7 )
FUNCTION Utf8ToWideStr( cText )
LOCAL nChars, cOut, nLen
IF Empty(cText)
RETURN ""
ENDIF
// Solicita número de caracteres wide necessários
nChars := DllCall( "kernel32.dll", DC_CALL_STD, "MultiByteToWideChar", ;
65001 /* UTF-8 */, ;
0, ;
cText, ;
-1, ;
0, ;
0 )
IF nChars <= 0
RETURN ""
ENDIF
// Aloca espaço para a string UTF-16 (2 bytes por wchar)
cOut := Space( nChars * 2 )
// Converte string UTF-8 para wide
nLen := DllCall( "kernel32.dll", DC_CALL_STD, "MultiByteToWideChar", ;
65001, ;
0, ;
cText, ;
-1, ;
@cOut, ;
nChars )
IF nLen <= 0
RETURN ""
ENDIF
RETURN cOut
FUNCTION PtrToStr( pChar )
LOCAL cRet := "", i := 0, cByte
DO WHILE .T.
cByte := MemoRead( pChar + i, 1 )
IF Empty(cByte) .OR. Asc(cByte) == 0
EXIT
ENDIF
cRet += cByte
i++
ENDDO
RETURN cRet
#pragma BEGINDUMP
#include <windows.h>
#include "winuser.h"
#include "hbapi.h"
HB_FUNC( CHAR_TO_WCHAR )
{
const char * pszAnsi = hb_parc(1); // parâmetro passado do xHarbour
static wchar_t wszBuffer[1024]; // buffer estático (válido após retorno)
if( !pszAnsi )
{
hb_retptr( NULL );
return;
}
MultiByteToWideChar(
CP_UTF8, // Entrada em UTF-8
0, // Nenhuma flag
pszAnsi, // String original
-1, // Até o CHR(0)
wszBuffer, // Buffer de destino
sizeof(wszBuffer) / sizeof(wchar_t) // Tamanho do buffer
);
hb_retptr( (void *) wszBuffer ); // retorna ponteiro para wchar_t*
}
#pragma ENDDUMPCódigo: Selecionar todos
TRY
oXls := XLExcel():New()
CATCH
msg := 'ERRO...: SICONFI/004' + CRLF
msg += 'O MS.Excel não esta Ativado ou Não instalada nesse Computador.' + CRLF
msg += 'Instale o MS Excel e atualize o Windows, para continuar com a exportação dos dados.' + CRLF
msg += 'Erro: ' + Ole2TxtError()
MsgError( msg )
lOk := .f.
Break
END
If File(mArq_)
IF !oXls:LoadBook( mArq_ )
? oXls:ErrorMsg()
msg := 'ERRO...: SICONFI/005' + CRLF +;
'Aviso..:Não consegui abrir a planilha (XLS) SICONFI na pasta: ' + mArq_
MsgAtencao( msg )
Break
END
Else
? 'Planilha não existe'
Endif
IF oXls:GetSheet(0) == NIL
? "Erro ao acessar a primeira sheet:", oXls:ErrorMsg()
oXls:CloseBook()
oXls:End()
Break
ENDIF
oXls:WriteNum(24, 1, 100.25) // Linha 25, Coluna B