Caro leitor,
É sempre importante lembrá-lo que a nossa equipe está sempre procurando oferecer uma revista cada vez
melhor e com um conteúdo mais diversificado, portanto fique à vontade para sugerir assuntos e ideias para artigos
futuros.
Para este mês não faremos diferente, com a ajuda de nosso colaborador Hamden Vogel, o qual preparou o artigo
“THVExcel - Exportando dados para o Excel com eficiência”, ele demonstra através de uma classe denominada “THVExcel”
quais os caminhos para encapsular toda uma implementação customizada e muito rápida para o Microsoft Excel, podendo
gerar de uma a mais planilhas para cada informação, realizando operações internas como formatação e auto expansão
das colunas. O colunista Ricardo Barbosa Crivelli traz o artigo intitulado “Desenvolvendo uma aplicação com Laravel”,
sendo que nesta primeira parte ele nos ensina a desenvolver uma biblioteca utilizando um dos principais frameworks da
atualidade, o “Laravel”, tornando o código muito simples e eficiente. Também nos ensina a utilizar via linha de comando
uma forma para automatizar os principais processos e o acesso ao banco de dados.
Desejo uma ótima leitura, um abraço e até o mês que vem!
Marcos César Silva
Diretor Técnico
Editorial
Desenvolvendo uma aplicação com Laravel
parte 1
Introdução
O Laravel é um framework PHP que teve seu desenvolvimento iniciado em 2011 e que em 2015 se tornou o
framework PHP com mais estrelas no GitHub e é hoje um dos frameworks mais utilizados no mundo todo.
Segundo o próprio site oficial, o Laravel tem foco no usuário final, ou seja, foca na simplicidade, clareza e
em fazer o trabalho proposto. É indicado para todos os tamanhos de projetos devido a sua estrutura e facilidade na
manutenção.
A aplicação
Antes de mais nada vamos criar uma visão geral do que será desenvolvido hoje. Nosso objetivo é criar uma
biblioteca virtual para toda as edições da The Club, ou seja, precisaremos armazenar as informações de todas as
edições da revista, artigos e autores.
Primeiros passos
Agora que nós já sabemos o nosso objetivo é hora de criarmos um novo projeto. Primeiramente será
necessário instalar o Instalador do Laravel e deve ser feito através do gerenciador de pacotes Composer.
Para isso entre com o comando abaixo no seu terminal:
composer global require "laravel/installer"
Vale lembrar que este processo pode levar um tempo para ser concluído. Após a instalação estar
finalizada nós podemos criar o nosso projeto. Execute o comando abaixo para criar um projeto:
laravel new biblioteca
Acesse a pasta e execute o servidor local com os comandos abaixo:
cd biblioteca
php artisan serve
Agora acesse o endereço http://localhost:8000 em seu navegador e veja que a aplicação já está
rodando. O resultado deverá ser semelhante à Figura 1.
Figura 01 - Página Inicial do Laravel.
O Laravel é baseado no framework Symfony e ele herdou uma de suas principais características e que na
minha opinião éo grande diferencial para melhorar o fluxo do desenvolvimento, o uso terminal. Se você digitar o
comando abaixo verá uma lista de comandos que você pode utilizar para facilitar o desenvolvimento.
php artisan list
Configurando a aplicação
Agora que nós já temos a aplicação funcionando é hora de definirmos alguns parâmetros como o banco
de dados, por exemplo. Para isso vamos editar o arquivo .env que está na raiz do nosso projeto. Altere as
seguintes propriedades:
APP_NAME=Biblioteca
APP_ENV=local
...
APP_URL=http://localhost:8000
...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=NOME_DO_BANCO
DB_USERNAME=USUARIO
DB_PASSWORD=SENHA
...
Não se esqueça de criar o banco de dados!
Autenticação
Vamos começar pela autenticação, afinal não queremos que a listagem seja acessada sem um controle.
Normalmente você já iria pensar em criar uma tabela no banco de dados para armazenar os usuários,
criptografar as senhas, criar uma página de login, uma de registro, uma para recuperar a senha e tudo mais correto?
Mas no Laravel tudo é um pouco (ou nesse caso, muito) mais fácil. Para criar toda uma infraestrutura de autenticação
basta executar o comando abaixo:
php artisan make:auth
Lindo não? Agora atualize a página de nossa aplicação e veja agora que no canto superior direito existem
alguns links relacionados à autenticação conforme ilustra a Figura 2.
Figura 02. Links para autenticação e registro de um novo usuário.
Criando a nossa aplicação
Vamos começar a desenvolver nossa aplicação pelas migrações, elas são responsáveis por criar e alterar a
estrutura das tabelas no banco de dados. Isso facilita muito quando trabalhamos com times de desenvolvimento e
ao realizar um deploy de uma nova versão de um sistema já em produção, pois garante que todas as modificações
no banco sejam replicadas e executadas na ordem correta.
Vamos começar pelos autores, a estrutura do banco será igual a Figura 3. Crie nossa migração através do
comando abaixo e para facilitar e convencionar nosso código, vamos criar as tabelas e controles em inglês.
php artisan make:migration --create=authors
create_authors_table
Note que foi criado um arquivo
em
database/migrations/[data]_create_authors_table.php. Vamos adicionar nossas
colunas dentro do método up():
...
public function up()
{
Schema::create('authors', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->text('biography');
$table->string('email');
$table->timestamps();
});
}
...
Figura 03. Diagrama do banco de dados da biblioteca
Note que nós definimos os campos da tabela dentro do PHP, assim quando executarmos o comando ele irá
automaticamente criar a tabela. O mesmo irá ocorrer quando for necessário alterar alguma tabela.
Agora vamos criar uma classe que irá representar um registro dessa tabela, as classes deste tipo são
conhecidas como Models. Para criar a model execute o comando abaixo:
php artisan make:model Author
O próximo passo, agora, é criar uma Factory para gerar dados de teste para nosso sistema. O Laravel conta com
duas ferramentas para nos auxiliar na criação de dados para teste, a primeira são as Factories que permitem definir que
tipo de dado cada coluna deve receber e os Seeders que são responsáveis por gerar os dados definidos na Factory e
armazenar no banco de dados.
Configurando o banco de dados
Como não esperamos um grande volume de acessos à nossa aplicação, nós iremos utilizar o SQLite como
exemplo, mas se você desejar adicionar outro sistema gerenciador de banco de dados (SGBD) ou até mesmo alterar
as configurações do SQLite, basta alterar a lista DATABASES do arquivo settings.py.
A comunidade defende que você deve tentar manter o mesmo SGBD nos ambientes de produção e
desenvolvimento para que você minimize os conflitos que podem ser causados pela mudança de plataforma.
Se você preferir mudar o nome do arquivo gerado, basta alterar o trecho em destaque:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Alterando as configurações de hora
Existem muitas configurações que podem ser alteradas no arquivo settings.py e uma delas é o fuso horário. Para
nos certificarmos que as configurações estão corretas vamos alterar a propriedade TIME_ZONE:
TIME_ZONE = 'America/Sao_Paulo'
Se você está em outra região basta consultar a lista de timezones na Wikipédia em
https://en.wikipedia.org/wiki/List_of_tz_database_time_zones.
Alterando o modo de DEBUG
O modo de debug ou de depuração, para quem não sabe, é o modo em que os erros são mostrados de forma
mais detalhada do que somente o código HTTP. Ele deve ser sempre False em produção, mas nesse caso vamos deixa-lo
como True.
DEBUG = True
Traduzindo a aplicação
A última configuração que iremos alterar no arquivo de configuração é a que diz respeito ao idioma das mensagens que são
geradas automaticamente. Altere a propriedade LANGUAGE_CODE para o português do Brasil alterando o código para:
LANGUAGE_CODE = 'pt-br'
Configurando as rotas
Um ponto que muita gente se perde no django é em relação às rotas, pois se você verificar o arquivo urls.py
está localizado na pasta do projeto (meusite/meusite/urls.py) e não da aplicação. Você pode utilizar
este arquivo para definir suas rotas, mas é mais usual delegar esta função para a aplicação.
Os mapeamentos são feitos através da variável urlpatterns que é uma lista de funções path().
Cada path() está associada à uma view específica, que será exibida caso o endereço corresponda a alguma regra.
Note que inicialmente a urlpatterns define que toda URL que contenha admin/ será mapeada para o
modulo admin.sites.url que contém as regras e mapeamentos para a área administrativa do site.
O arquivo contém também as instruções de como mapear uma URL:
"""meusite URL Configuration
The ̀ urlpatterns` list routes URLs to views. For more information
please see:
https://docs.djangoproject.com/en/2.0/topics/http/urls/
Examples:
Function views
Add an import: from my_app import views
Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
Add an import: from other_app.views import Home
Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
Import the include() function: from django.urls import include,
path
2. Add a URL to urlpatterns: path('blog/',
include('blog.urls'))
"""
Adicione o código abaixo para que qualquer URL com o prefixo biblioteca/ seja enviado para o
módulo biblioteca.urls que será armazenado no arquivo biblioteca/urls.py. As alterações
e inclusões estão em negrito.
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('biblioteca/', include('biblioteca.urls')),
]
Redirecionando a URL raiz
Como nós só teremos a biblioteca em nosso projeto (pelo menos até agora), seria interessante redirecionar quem
acessar a URL raiz (a 127.0.0.1:8000, por exemplo) para o endereço da biblioteca. Adicione o código em negrito
para o arquivo urls.py:
...
from django.conf.urls import include
from django.views.generic import RedirectView
urlpatterns = [
path('admin/', admin.site.urls),
path('biblioteca/', include('biblioteca.urls')),
path('', RedirectView.as_view(url='/biblioteca/')),
]
Servindo arquivos CSS e JavaScript
O Django por padrão não serve arquivos estáticos como CSS, JavaScript e imagens, mas sabemos que isso
é de extrema importância no desenvolvimento de nossa aplicação. A solução é bastante simples, basta adicionar o
código abaixo para que o servidor forneça os arquivos estáticos quando requisitados:
...
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('biblioteca/', include('biblioteca.urls')),
path('', RedirectView.as_view(url='/biblioteca/')),
]
urlpatterns += static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT);
Você notou que nós concatenamos a função static à urlpatterns? O Python é tão versátil que isso pode ser
feito inline se você preferir:
urlpatterns = [
path('admin/', admin.site.urls)
path('biblioteca/', include('biblioteca.urls')),
path('', RedirectView.as_view(url='/biblioteca/')),
]+ static(settings.STATIC_URL,
document_root=settings.STATIC_ROOT);
Testando
Vamos executar o servidor para testar a nossa aplicação através do comando:
python3 manage.py runserver
Ou se você estiver no Windows:
py -3 manage.py runserver
Agora acesse a URL http://127.0.0.1:8000 e veja que o resultado é uma página de erro 404.
Ela indica que a página não pode ser encontrada, ou seja, nossa aplicação está funcionando como deveria já que
nós ainda não criamos nenhuma página! Esse será o próximo passo que veremos no artigo do mês que vem!
Conclusão
No artigo de hoje aprendemos a criar uma nova aplicação em um projeto Django e como configuramos as
rotas para que possamos iniciar o desenvolvimento das views. Aprendemos também um pouco sobre um dos
arquivos mais importantes do Django, o settings.py,responsável por armazenar todas as configurações do
projeto.
Sobre o Autor
Ricardo Barbosa Crivelli, mais conhecido como Rico Crivelli, é formado como Bacharel
em Sistemas de Informação e Licenciado em Computação pela Universidade Estadual do Norte do
Paraná e pós-graduando em Informática na Educação. Atualmente é Técnico em TI no Instituto Federal de São Paulo – Câmpus Avaré. Tem como especialidade a linguagem PHP e o framework
Symfony, apesar de adorar trabalhar com front-end e desenvolvimento mobile. Possuir as
certificações COBiT 4.1 Foundation e Delphi 2006 Developer. E-mail para contato: [email protected]
E-mail: [email protected]
THVExcel - Exportando dados para o Excel com eficiência.
Uma das coisas mais intrigantes no que diz respeito à exportação de dados é a rotina para
comunicação com o Excel – como fazer isso de forma simples, ágil e eficiente? Inúmeros aplicativos
necessitam trocar informações com outros aplicativos da família Microsoft, que é o foco deste artigo, e
com frequência vimos objetos de DBGrids e StringGrids sendo exportados em planilhas do Excel,
formatadas, estilo de tabelas, fontes cabeçalho negrito, fórmulas embutidas nas células em runtime,
gráficos, macros, etc.; pra tudo isso precisamos realmente de uma classe que automatize todo este
processo que é tedioso, pois a manipulação destes dados via recurso OLE (Object Linking and
Embedding) – que é um método da Microsoft pra comunicação com seus aplicativos para com o Excel,
neste nosso caso, simplificadamente falando (não vamos abordar esta arquitetura no escopo deste
artigo; vamos focar realmente no que interessa que é a exportação para o Excel).
A melhor maneira que observei neste caso foi a criação de uma classe na qual eu batizo de
THVExcel. Ela fará todo o trabalho “sujo”, de criação de um objeto via OLE que gerencie em um escopo
local todo o ciclo de vida de um objeto “Excel.Application”; encapsuladamente poderemos repassar aos
parâmetros de opções desta classe toda uma gama de configurações das planilhas instantâneas –
opções como por exemplo – gerar datasets em apenas uma planilha; auto formatar valores e cabeçalhos;
aplicar fonte negrito no cabeçalho; auto expansão das células; aplicar formato de tabela
automaticamente, etc. Em muitas funções que notei que fazem este processo – muitas falham por não pensarem na
agilidade e eficiência – acabam sendo um “tiro no pé” por demorarem demais para a criação destes
documentos em tempo de execução – a melhor forma, que apresento aqui com esta classe, é utilizar
um array do tipo Variant e aplicar o conteúdo dele como resultado do método “Range” de um objeto
OLEVariant (que é a planilha em si) – com isso, centenas ou até milhares de células do Excel serão
geradas rapidamente demonstrando enorme eficiência, desonerando a memória do seu aplicativo e do
Windows.
A classe THVExcel recebe os datasets (que podem estar associados a um DBGrid ou em qualquer
lugar – podendo ser até em memória, como um objeto de TClientDataSet, etc.), podendo configurar
seus atributos como nome físico e alias e finalmente especificar um nome completo de gravação;
informa ao usuário que arquivo Excel foi criado com sucesso e pronto! Com poucas linhas de código
para chamar esta classe e a funcionalidade estará definida. Simples para reutilização de código-fonte,
fácil de ser chamada e igualmente fácil de ser estendida – podemos pensar futuramente para melhorar
a integração com alguns componentes como StringGrid direto para o Excel, por exemplo (de forma
eficiente utilizando arrays de variant).
Figura 01 - Tela inicial da nossa exportação para o Excel. Vide botão “Exportar Dados para o Excel” situado no canto inferior à direita.
Var
hvExcel: THVExcel;
{ ... }
hvExcel := THVExcel.Create;
try
hvExcel.Add(ClientDataSet1, 'Sheet 1');
hvExcel.Add(ClientDataSet2, 'Sheet 2');
hvExcel.Add(ClientDataSet3, 'Sheet 3');
hvExcel.FileName := 'C:\teste.xls';
hvExcel.AllDataSetsInOneSheet := False;
hvExcel.ExportToExcel;
finally
FreeAndNil(hvExcel);
end;
Acima vimos um código-fonte de como chamar esta classe e executar alguns parâmetros
básicos para o seu funcionamento. Neste exemplo três datasets são exportados em três planilhas
respectivas.
Como disse anteriormente, a melhor técnica é quando você utiliza arrays de variants. Vamos
mostrar mais abaixo como esse código resolve a vida do desenvolvedor tornando rápida a exportação
para o Excel, gerando o arquivo com as planilhas desejadas, com as opções já customizadas pelo
componente.
Figura 02 - Mensagem de confirmação do próprio Excel, para sobreescrever um arquivo já gerado por ele.
Figura 03 – Mensagem de informação exibida pelo nossa classe THVExcel.
Figura 04 – Arquivo Excel criado pela classe THVExcel.
Segue abaixo alguns trechos da nossa classe:
Var
arrData: Variant; i, j: integer; Range: OLEVariant;
begin
if objDataSet.RecordCount = 0 then Exit;
arrData := VarArrayCreate([0,
objDataSet.RecordCount+1, 0, objDataSet.FieldCount],
varVariant);
for j := 0 to objDataSet.FieldCount - 1 do arrData[0,
j] := objDataSet.Fields[j].FieldName;
i := 1;
objDataSet.DisableControls;
objDataSet.First;
try
while not objDataSet.Eof do
begin
for j := 0 to objDataSet.FieldCount - 1 do
arrData[i,j]:=objDataSet.Fields[j].AsString;
//objDataSet.Fields[j].AsString;
Inc(i);
objDataSet.Next;
end;
finally
objDataSet.First;
objDataSet.EnableControls;
end;
Range:=objXLWorkbook.ActiveSheet.Range[objXLWorkbook.
ActiveSheet.Cells[1, 1],
objXLWorkbook.ActiveSheet.Cells[objDataSet.RecordCount+
1, objDataSet.FieldCount]];
Range.Value := arrData;
end;
Código-Fonte da rotina de exportação, utilizando arrays do tipo variant.
Podemos ver que passamos um objeto da classe TDataSetArrayProperties para cada chamada
do método Add, que por sua vez chama internamente um objeto de TStringList em que é finalmente
utilizado em seu parâmetro AddObject.
TDataSetArrayProperties = class(TPersistent)
Private
FSheetName: string;
public
property SheetName: String read FSheetName write
FSheetName;
end;
procedure THVExcel.Add(objDataSet: TDataSet; const
SheetName: string = '' );
begin
SetLength(Self.DataSetArray,
length(Self.DataSetArray)+1);
Self.DataSetArray[high(self.DataSetArray)] :=
objDataSet;
ifDataSetArrayProperties :=
TDataSetArrayProperties.Create;
if SheetName <> '' then
fDataSetArrayProperties.SheetName := SheetName
else
fDataSetArrayProperties.SheetName :=
objDataSet.Name;
strLstDataSetArray.AddObject(fDataSetArrayProperties.
SheetName, fDataSetArrayProperties);
end;
end;
Código-Fonte da classe TDataSetArrayProperties em uma TStringList.
Podemos passar qualquer tipo de objeto para um TStringList qualquer, e no nosso caso quisemos
passar uma classe de opções como parâmetro. Isso é bom porque podemos recuperar facilmente este
objeto, como podemos ver abaixo:
function THVExcel.ExportToExcel: Boolean;
Var
i: integer;
begin
if Length(Self.DataSetArray) = 0 then Exit;
if Self.strLstDataSetArray.Count = 0 then Exit;
for i := 0 to length(Self.dataSetArray)-1 do
begin
Self.ExportDataSet(Self.dataSet[i],
TDataSetArrayProperties(Self.strLstDataSetArray.Objects[i]).
SheetName);
end;
end;
Conclusão
Vimos uma maneira alternativa e muito eficiente de geração de documentos para o Excel; de forma
fácil de se utilizar em seus projetos; com poucas linhas de código-fonte e com algumas parametrizações já
setadas como padrão pela classe; tornando o processo que antes era tedioso em um novo processo mais
tranquilo para a implementação, bastando empregar seus métodos para seu funcionamento ou então
aprimorar eles para uma nova release, evoluindo e contribuindo para seu melhor trabalho para com este
componente.
A parte de criação de planilhas, gerenciáveis pela classe, onde uma delas contém todos os datasets ou então um
dataset pra cada planilha respectiva é um trabalho extra de codificação “chata” que será feito apenas uma vez, livrando o
programador de “reinventar a roda” destas particularidades que demandam tempo em tentativa e erro; esta classe
THVExcel não será encontrada com esta facilidade em nenhum lugar na web – tampouco com sua implementação rica de
detalhes de opções com uma interface bem intuitiva de utilizar com seus métodos claros e com duas opções de invocação
do construtor dela.
Aproveito para desejar bons projetos e sucesso com esta classe em seus projetos, e bons estudos
com esta implementação!
Sobre o Autor
Hamden Vogel, Consultor TheClub
E-mail: [email protected]
Recommended