Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Fala pessoal!
Hoje precisei criar uma rotina para importação de arquivos OFX, aqueles que são usados para fazer integração bancária.
Esse arquivos nada mais são do que o extrato bancário em um formato universal para integração com vários tipos de sistemas e linguagens de programação.
Como não é uma coisa que se acha fácil por ai, resolvi postar e deixar disponível para quem precisar.
Código do arquivo Ofx.php
<?phpclass Ofx { private $ofxFile; public function __construct($ofxFile) { $this->ofxFile = $ofxFile; } /* * Converte o arquivo OFX para XML */ public function getOfxAsXML() { $content = file_get_contents($this->ofxFile); $line = strpos($content, "<OFX>"); $ofx = substr($content, $line - 1); $buffer = $ofx; $count = 0; while ($pos = strpos($buffer, '<')) { $count++; $pos2 = strpos($buffer, '>'); $element = substr($buffer, $pos + 1, $pos2 - $pos - 1); if (substr($element, 0, 1) == '/') $sla[] = substr($element, 1); else $als[] = $element; $buffer = substr($buffer, $pos2 + 1); } $adif = array_diff($als, $sla); $adif = array_unique($adif); $ofxy = $ofx; foreach ($adif as $dif) { $dpos = 0; while ($dpos = strpos($ofxy, $dif, $dpos + 1)) { $npos = strpos($ofxy, '<', $dpos + 1); $ofxy = substr_replace($ofxy, "</$dif>\n<", $npos, 1); $dpos = $npos + strlen($element) + 3; } } $ofxy = str_replace('&', '&', $ofxy); return $ofxy; } /* * Retorna o Saldo da conta na data de exportação do extrato */ public function getBalance() { $xml = new SimpleXMLElement($this->getOfxAsXML()); $balance = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->LEDGERBAL->BALAMT; $dateOfBalance = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->LEDGERBAL->DTASOF; $date = strtotime(substr($dateOfBalance, 0, 8)); $dateToReturn = date('Y-m-d', $date); return Array('date' => $dateToReturn, 'balance' => $balance); } /* * Retora um array de objetos com as transações * * DTPOSTED => Data da Transação * TRNAMT => Valor da Transação * TRNTYPE => Tipo da Transação (Débito ou Crédito) * MEMO => Descrição da transação */ public function getTransactions() { $xml = new SimpleXMLElement($this->getOfxAsXML()); $transactions = $xml->BANKMSGSRSV1->STMTTRNRS->STMTRS->BANKTRANLIST->STMTTRN; return $transactions; }}
Exemplo de utilização:
<?phprequire_once 'Ofx.php';$ofx = new Ofx('extrato.ofx');$saldo = $ofx->getBalance();?><html> <head> <title>Transações</title> </head> <body> <h1>Seu saldo em <?php echo date("d/m/Y", strtotime($saldo['date'])); ?> é de R$ <?echo $saldo['balance']; ?></h1> <h2>Transações</h2> <table border="1" cellpadding="3" cellspacing="0"> <thead> <tr> <th>Data</th> <th>Descrição</th> <th>Tipo</th> <th>Valor</th> </tr> </thead> <tbody> <?php foreach ($ofx->getTransactions() as $transaction) : ?> <tr> <td><?php echo date("Y-m-d", strtotime(substr($transaction->DTPOSTED, 0, 8))); ?></td> <td><?php echo $transaction->MEMO; ?></td> <td><?php echo $transaction->TRNTYPE; ?></td> <td><?php echo $transaction->TRNAMT; ?></td> </tr> <?php endforeach; ?> </tbody> </table> </body></html>
É isso ai, espero que seja útil!
Excelente post.
Aqui deu certinho (só não testei com acentos rsss).
Abs
Flávio
www.devfuria.com.br
Parabéns! Ótima iniciativa
Funcionou perfeito. Resolvido
Rapaz não tenho como te agradecer. Mandou super bem!! Parabéns!
Olá Emerson.
Muito Obrigado pelo post..
mais cara infelizmente na minha maquina o código não funciona
gera vários erros de WARNiNG: SIMPLEXMLELEMENT,
ainda sou meio leigo em php e gostaria muito de sua ajuda.
não teria como postar o código zipado para download juntamente com um exemplo
de arquivo ofx.
Att. Alessandro
Pra quem está tento problemas com a codificação do arquivo OFX altere a linha
$content = file_get_contents($this->ofxFile);
para:
$content = utf8_decode(file_get_contents($this->ofxFile));
isso deve resolver
Emerson, muito obrigado. Mesmo após 2.5 anos seu post me ajudou demais.
Só deu problema em casos de OFX's provenientes do Banco do Brasil.
Aparentemente é porque os arquivos não fecham algumas tags aí dá erro.
Emerson, valeu pelo post... ajudou muito.
Devy++, tive o mesmo problema e resolvi assim:
public function __construct($ofxFile) {
$this->ofxFile = $this->closeTags($ofxFile);
}
public function closeTags($ofx=null) {
$buffer = '';
$source = fopen($ofx, 'r') or die("Unable to open file!");
while(!feof($source)) {
$line = trim(fgets($source));
if ($line === '') continue;
if (substr($line, -1, 1) !== '>') {
list($tag) = explode('>', $line, 2);
$line .= '</' . substr($tag, 1) . '>';
}
$buffer .= $line ."\n";
}
$name = realpath(dirname($ofx)) . '/' . date('Ymd') . '.ofx';
$file = fopen($name, "w") or die("Unable to open file!");
fwrite($file, $buffer);
fclose($file);
return $name;
}Bom dia Colegas :D
resolvi tomar a liberdade de pegar o codigo que é muito util e colocar aqui
algo tao util como isso nao pode se perder :D
composer require asmpkg/ofx
Mano esse código é sensacional, parabéns pela iniciativa, me salvou
>
Em 14/06/2017 at 12:06, aMaltha disse:
Emerson, valeu pelo post... ajudou muito.
Devy++, tive o mesmo problema e resolvi assim:
public function __construct($ofxFile) {
$this->ofxFile = $this->closeTags($ofxFile);
}
public function closeTags($ofx=null) {
$buffer = '';
$source = fopen($ofx, 'r') or die("Unable to open file!");
while(!feof($source)) {
$line = trim(fgets($source));
if ($line === '') continue;
if (substr($line, -1, 1) !== '>') {
list($tag) = explode('>', $line, 2);
$line .= '</' . substr($tag, 1) . '>';
}
$buffer .= $line ."\n";
}
$name = realpath(dirname($ofx)) . '/' . date('Ymd') . '.ofx';
$file = fopen($name, "w") or die("Unable to open file!");
fwrite($file, $buffer);
fclose($file);
return $name;
}Esse arquivo é o máximo!
Mas "aMaltha" eu não consegui usar sua adaptação. Continuo não podendo usar BB.
o composer nao esta instalando da a mensagem de erro abaixo --- alguem pode ajudar -- preciso importar o .ofx e gravar no Banco de Dados mysql
[InvalidArgumentException]
Could not find a version of package asmpkg/ofx matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desir
ed stability.
Esse código tem problema se o cara usar uma palavra reservada na descrição do extrato bancário,
E seria interessante bufferizar somente 1x;
mas enfim quem esta querendo resolver algum problema em código de manutenção na empresa como eu:
$ofxy = $ofx;
foreach ($adif as $dif) {
$dpos = 0;
$npos = strpos($ofxy, '<', $dpos + 1);
$ofxy = substr_replace($ofxy, "</$dif>\n<", $npos, 1);
$dpos = $npos + strlen($element) + 3;
}
}
$ofxy = str_replace('&', '&', $ofxy);
return $ofxy;
Está dando erro quando tem acentos na descrição