avro /csv-bundle
Symfony2 CSV Bundle
Requires
- php: ^7.1 || ^8.0
- ext-json: *
- misatotremor/case-bundle: ^1.0.0
Requires (Dev)
- doctrine/doctrine-bundle: ^1.12|^2.0
- doctrine/orm: ^2.8
- phpunit/phpunit: ^7.5 || ^8.5 || ^9.3 || ^10.0
- symfony/event-dispatcher: ^4.4|^5.0|^6.0
- symfony/form: ^4.4|^5.0|^6.0
- symfony/framework-bundle: ^4.4|^5.0|^6.0
- symfony/phpunit-bridge: ^4.4|^5.0|^6.0
- symfony/routing: ^4.4|^5.0|^6.0
README
此Bundle提供了一种简单的方法,通过仅配置少量参数,使用CSV文件将数据上传到您的数据库。
状态
此Bundle处于开发阶段,可能会出现错误。
限制
此Bundle使用php和Doctrine2,不是导入巨大型CSV文件的最佳选择。请使用您数据库的本地导入和导出解决方案。
特性
- 通过CSV文件导入数据
- 将数据导出到CSV文件
- 一些用于读取/写入CSV文件的服务
支持
- Doctrine ORM
安装
此Bundle已列在Packagist上。
只需将其添加到您的应用的composer.json文件中
"avro/csv-bundle": "^0.4.2"
同时启用config/bundles.php中的Bundle以及相关的AvroCaseBundle
Avro\CsvBundle\AvroCsvBundle::class => ['all' => true], Avro\CaseBundle\AvroCaseBundle::class => ['all' => true],
配置
添加以下必需配置
# config/packages/avro_csv.yaml avro_csv: db_driver: orm # supports orm batch_size: 15 # The batch size between flushing & clearing the doctrine object manager tmp_upload_dir: "%kernel.root_dir%/../web/uploads/tmp/" # The directory to upload the csv files to sample_count: 5 # The number of sample rows to show during mapping
将路由添加到您的配置中
# config/routes/avro_csv.yaml avro_csv: resource: "@AvroCsvBundle/Resources/config/routing.yml"
添加您想要实现导入/导出的实体/文档
# config/packages/avro_csv.yaml avro_csv: # objects: # the entities/documents you want to be able to import/export data with client: class: Avro\CrmBundle\Entity\Client # The entity/document class redirect_route: avro_crm_client_list # The route to redirect to after import invoice: class: Avro\CrmBundle\Entity\Invoice redirect_route: avro_crm_invoice_list
要排除某些字段映射,请使用ImportExclude注释,如下所示。
namespace Avro\CrmBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Avro\CsvBundle\Annotation\ImportExclude; /** * Avro\CrmBundle\Entity\Client * * @ORM\Entity */ class Client { /** * @var string * * @ORM\Column(type="string", length=100, nullable=true) * @ImportExclude */ protected $password;
导入
为任何数量的实体/文档实现导入。您只需将它们添加到前面提到的对象节点中。
然后只需包含一个指向特定导入页面的链接,如下所示
<a href="{{ path('avro_csv_import_upload', {'alias': 'client'}) }}">Go to import page</a>
将"client"替换为您在配置中指定的实体/文档的别名。
视图
此Bundle附带了一些基本的Twitter Bootstrap视图,您可以通过扩展Bundle来覆盖它们。
关联映射
在导入关联字段时,会触发一个事件,以允许实现适合您自己的逻辑。
只需在您的应用中创建一个自定义监听器,以监听AssociationFieldEvent::class
事件。
一个简单的实现,通过名称获取关联实体,可能如下所示
namespace App\EventListener; use Avro\CsvBundle\Event\AssociationFieldEvent; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Mapping\ClassMetadataInfo; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** * Csv import listener */ class ImportListener implements EventSubscriberInterface { private $em; /** * @param EntityManagerInterface $em The entity manager */ public function __construct(EntityManagerInterface $em) { $this->em = $em; } public static function getSubscribedEvents() { return [ AssociationFieldEvent::class => 'importAssociation', ]; } /** * Set the objects createdBy field * * @param AssociationFieldEvent $event */ public function importAssociation(AssociationFieldEvent $event) { $association = $event->getAssociationMapping(); switch ($association['type']) { case ClassMetadataInfo::ONE_TO_ONE: case ClassMetadataInfo::MANY_TO_ONE: $relation = $this->em->getRepository($association['targetEntity'])->findOneBy( [ 'name' => $event->getRow()[$event->getIndex()], ] ); if ($relation) { $event->getObject()->{'set'.ucfirst($association['fieldName'])}($relation); } break; } } }
自定义每一行
想要自定义每一行上的某些字段?没问题。
当添加行时,会触发一个事件,您可以利用此事件来自定义每行数据。
只需在您的应用中创建一个自定义监听器,以监听RowAddedEvent::class
事件。
例如...
namespace App\EventListener; use Avro\CsvBundle\Event\RowAddedEvent; use Doctrine\ORM\EntityManagerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\SecurityContextInterface; /** * Csv import listener */ class ImportListener implements EventSubscriberInterface { private $em; private $context; /** * @param EntityManagerInterface $em The entity manager * @param SecurityContextInterface $context The security context */ public function __construct(EntityManagerInterface $em, SecurityContextInterface $context) { $this->em = $em; $this->context = $context; } public static function getSubscribedEvents() { return [ RowAddedEvent::class => 'setCreatedBy', ]; } /** * Set the objects createdBy field * * @param RowAddedEvent $event */ public function setCreatedBy(RowAddedEvent $event) { $object = $event->getObject(); $user = $this->context->getToken()->getUser(); $object->setCreatedBy($user); } }
注册您的监听器或使用自动装配
导出
此Bundle提供了一些简单的导出功能。
导航到"/export/your-alias"将导出所有数据到CSV,并允许您从浏览器下载。
您可以通过监听相应的事件(请参阅Avro\CsvBundle\Event
命名空间中的事件)来自定义导出查询构建器和导出数据。
如果想要自定义返回的数据,只需创建自己的控制器操作,并从导出器中获取queryBuilder,在调用"getContent()"之前添加约束。
例.
namespace App\Controller; use Avro\CsvBundle\Export\ExporterInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; class ExportController extends AbstractController { /** * Export a db table. * * @param ExporterInterface $exporter The exporter * @param string $alias The objects alias * * @return Response */ public function exportAction(ExporterInterface $exporter, string $alias): Response { $class = $this->getParameter(sprintf('avro_csv.objects.%s.class', $alias)); $exporter->init($class); // customize the query $qb = $exporter->getQueryBuilder(); $qb->where('o.fieldName =? 1')->setParameter(1, false); $content = $exporter->getContent(); $response = new Response($content); $response->headers->set('Content-Type', 'application/csv'); $response->headers->set('Content-Disposition', sprintf('attachment; filename="%s.csv"', $alias)); return $response; } }
注册您的控制器或使用您已经设置的自动装配
待办事项
- 完成MongoDB支持
致谢
感谢jwage的EasyCSV为一些基础工作。
反馈和拉取请求非常欢迎!