


Utilisez EasyPOI pour exporter avec élégance les données du modèle Excel (y compris les images)
Avant-propos
Récemment, un lecteur posait des questions sur easypoi, j'ai donc pris le temps de rédiger un article.
Texte
La fonction d'EasyPOI est tout comme le nom Easy. La fonction principale est la facilité, afin qu'une personne qui n'a jamais été exposée à POI puisse facilement écrire une exportation Excel, une exportation de modèle Excel, une importation Excel et Word. exportation de modèles. Grâce à des annotations simples et à un langage de modèle (syntaxe d'expression familière), des méthodes d'écriture auparavant complexes peuvent être complétées.
Cet article utilise principalement une analyse simple pour permettre aux lecteurs de savoir comment rédiger des modèles Excel et comment utiliser EasyPOI pour exporter des données Excel qui répondent à leurs besoins, simplifiant ainsi le codage. Parallèlement, cet article expliquera également certaines fonctions peu courantes comme la fonction d'exportation d'images, afin que les lecteurs puissent éviter les pièges.
Instructions de version et de dépendance
EasyPOI4.0.0 et les versions ultérieures dépendent d'Apache POI 4.0.0 et des versions ultérieures. Par conséquent, dans la configuration maven, les numéros de version des deux doivent correspondre.
Il convient de noter qu'Apache POI 4.0.0 présente des changements importants par rapport à la version précédente. Si la partie opération Excel du code précédent dépend de l'ancienne version, il n'est pas recommandé d'utiliser la version 4.0.0 et les versions ultérieures. Bien entendu, si le code précédent n’implique pas ou implique rarement les détails de création de WorkBook, l’utilisation de la nouvelle version ne pose aucun problème.
Le projet que l'auteur doit réécrire est basé sur JEECG version 3.7 et s'appuie sur la version 3.9 d'Apache POI. La version la plus élevée de jeasypoi maintenue par JEECG n'est que la 2.2.0, et cette version ne prend pas en charge la fonction d'exportation d'image de modèle. En parlant de ça, je veux me plaindre de l'équipe JEECG suivante. Puisque je n'ai pas l'intention de maintenir jeasypoi, pourquoi ne pas simplement utiliser l'EasyPOI officiel directement dans le projet. Combien de fosses la version 2.2.0 de jeasypoi a-t-elle creusées pour les développeurs ? ?
Afin d'être compatible avec l'ancienne version et de vouloir utiliser la fonction d'export d'images apportée par EasyPOI, la version EasyPOI que j'ai finalement adoptée est la 3.3.0, et la dépendance Apache POI correspondante est la 3.15.
La configuration de Maven est la suivante :
<properties> <poi.version>3.15</poi.version> <easypoi.version>3.3.0</easypoi.version> </properties> <dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml-schemas</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>${poi.version}</version> </dependency> <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-web</artifactId> <version>${easypoi.version}</version> </dependency> </dependencies>
Conception de modèle Excel
Nous utilisons la fonction d'exportation de modèle d'EasyPOI car nous ne voulons pas concevoir le style du rapport Excel via le codage, donc le premier L'étape du travail consiste à concevoir le modèle Excel et à distinguer clairement quelles parties sont fixes et quelles parties doivent être remplies en boucle. EasyPOI possède son propre langage d'expression. Pour une introduction détaillée de chaque expression, veuillez vous référer au lien de référence ci-dessous.
Un modèle de rapport Excel simple
Certains modèles simples ne seront pas expliqués en détail ici, seuls les rendus et le contenu de configuration du modèle seront affichés. Lorsque les lecteurs comprendront comment créer des modèles complexes et remplir des valeurs, les plus simples seront rapidement compris.
Premier coup d'œil aux rendus du rapport :
Ensuite, regardez le modèle lui-même :
Après avoir regardé les deux images ci-dessus, avez-vous déjà ressenti la puissance de la fonction d'exportation de modèles ?
Un modèle de rapport Excel complexe
Le modèle à présenter ci-dessous est relativement complexe, contrairement à la situation courante où une ligne est un enregistrement, donc la configuration du modèle sera présentée en détail, et par la manière Une brève introduction à quelques expressions d'EasyPOI.
Regardons d'abord les rendus :
Ensuite, regardons le modèle :
En comparant ces deux images, avez-vous l'impression que la connaissance peut changer votre destin ?
Analyse de la conception d'un modèle complexe
À partir des images du modèle et des rendus des informations sur le produit, nous avons constaté que l'ensemble du modèle est en fait divisé en parties supérieure et inférieure. La partie supérieure correspond aux informations d'en-tête inchangées et la partie inférieure correspond aux informations détaillées sur le produit insérées de manière cyclique. Nous nous concentrons donc sur la grammaire dans la seconde moitié.
La première colonne dans la moitié inférieure de l'image n'est pas affichée complètement, il s'agit en fait de {{!fe: list t.id.
Remarque, il n'y a pas de symbole }} ici ! Selon la documentation officielle d'EasyPOI, {{}} représente une expression et la valeur à l'intérieur est obtenue en fonction de l'expression. Si vous regardez attentivement l'image, vous constaterez que le symbole de clôture {{}} de l'expression apparaît dans le coin inférieur droit de l'image. C'est-à-dire qu'à partir de la première colonne {{ et se terminant dans le coin inférieur droit}}, tout le reste fait partie de l'expression.
Étant donné que toutes les informations du modèle font partie de l'expression, même les chaînes ordinaires doivent être spécialement marquées. Les sous-expressions de l'expression sont expliquées une par une ci-dessous.
!fe : Parcourez les données sans créer de lignes.
Cette phrase du document officiel peut être un peu déroutante à comprendre pour tout le monde. Que signifie ne pas créer de dispute ? En fait, ne pas créer de ligne est relatif à la création d'une ligne, et l'expression pour créer une ligne est fe :.
Tout comme chaque enregistrement de la base de données correspond à un objet entité, créer une ligne signifie que chaque ligne est un objet entité. Les attributs de cet objet entité sont encapsulés avec des expressions {{}}.
Ne pas créer de ligne signifie qu'il n'y a qu'un seul objet entité Objet dans l'expression entière, mais cet objet est spécial. Il est assemblé par N entités dans la liste. Chaque entité fait non seulement référence au modèle lui-même, mais inclut également le style Excel, comme le nombre de cellules qu'elle occupe, les coordonnées des cellules, l'ordre de disposition, etc.
list est un nom personnalisé qui représente la collection de données dans l'expression. Le code utilise list comme clé pour obtenir la collection de valeursà partir de Map
La liste de noms est facile à comprendre. Il ne s'agit que d'un espace réservé et peut être choisi avec désinvolture. Lorsque EasyPOI analyse la liste, il saura qu'il existe un ensemble de valeurs de la clé dans Map
Recherchez sur le compte officiel Java Zhiyin, répondez « Backend Interview » et nous vous donnerons un guide de questions d'entretien Java.pdf
t valeur prédéfinie, représentant n'importe quel objet de la collection.
Nous pouvons à peu près sentir à partir du modèle que chaque objet de la liste est appelé t, et t.name représente l'attribut name de t, donc le nom t peut être appelé avec désinvolture. Quoi qu'il en soit, c'est la même chose que list, et. il fonctionne comme un espace réservé.
Mais en réalité, c'est un grand gouffre ! Si vous remplacez t par une autre valeur telle que g, écrivez g.name g.code, etc. ailleurs dans le modèle, il ne sera finalement pas analysé ! La documentation officielle n’insiste pas sur ce point, mais l’auteur ne l’a découvert qu’après avoir marché sur le piège !
]] Caractère de nouvelle ligne Exportation traversante multiligne.
L'explication officielle de ce symbole est également déroutante. Qu'est-ce qu'un caractère de nouvelle ligne et une exportation de parcours multiligne ? En fait, cela signifie que lorsque l'expression contient ce symbole, le contenu après la ligne ne sera pas analysé, qu'il y ait ou non un autre contenu ou un autre style derrière.
Ce symbole doit être écrit dans la dernière colonne de chaque ligne, sinon le nombre de lignes et de colonnes sera différent et une exception de pointeur nul sera signalée lorsque EasyPOI effectuera une affectation interne.
'' Un guillemet simple représente une valeur constante '' Par exemple, « 1 », alors le résultat est 1
L'introduction ici dans le document officiel comporte également des pièges. '' signifie valeur constante, mais en fait, c'est une erreur de l'avoir uniquement dans Excel, car lorsque Excel rencontre ' dans une cellule, il pensera que ce qui suit sont toutes des chaînes, vous devez donc écrire '' type de bibliothèque : ' dans la cellule. , de sorte que ce qui est affiché est « Type de bibliothèque : », et non le type de bibliothèque de chaînes : ».
Après l'analyse ci-dessus, le modèle dans l'image est en fait similaire au suivant :
{{!fe: list t.id ‘库别:’ t.bin 换行 ‘商品名称:’ t.name 换行 ‘商品编号:’ t.code t.barcode 换行 ‘生产日期:’ t.proDate 换行 ‘进货日期:’ t.recvDate}}
如果list中有多条记录,上述字符串就再循环拼接一些内容,最终都在一个{{}}表达式中。
至此,模板的设计已剖析完毕,读者可根据自己的需求结合官方文档自行设计模板。下面将对模板赋值进行介绍。
准备模板数据
从上节的描述中可知,只需要准备一个Map
Map<String, Object> total = new HashMap<>(); List<Map<String, Object>> mapList = new ArrayList<>(); for (int i = 1; i <= 5; i++) { Map<String, Object> map = new HashMap<>(); map.put("id", i + ""); map.put("bin", "001 1000千克"); map.put("name", "商品" + i); map.put("code", "goods" + i); map.put("proDate", "2019-05-30"); map.put("recvDate", "2019-07-07"); // 插入图片 ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); ImageIO.write(bufferImg, "jpg", byteArrayOut); ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); map.put("barcode", imageEntity); mapList.add(map); } total.put("list", mapList);
图片数据导出
上述代码中需要特殊关注的是图片导出部分。EasyPOI导出图片有两种方式,一种是通过图片的Url,还有一种是获取图片的byte[]
,毕竟图片的本质就是byte[]
。因为笔者的项目中图片不是存放在数据库之中,而是需要根据查询结果动态生成条码,所以通过byte[]
导出图片。
ImageEntity是EasyPOI内置的一个JavaBean,用于设定图片的宽度和高度、导出方式、RowSpan和ColumnSpan等。调试EasyPOI的源码可知,当设置了RowSpan或者ColumnSpan之后,图片的高度设置就失效了,图片大小会自动填充图片所在的单元格。
图片导出的坑点在于导出图片的大小。假设我们将四个单元格合成为一个,希望导出的图片能填充合并之后的单元格,但是对不起,EasyPOI暂时做不到,它只会填充合并之前左上角的单元格,具体原因如下源码所示:
//BaseExportService.java ClientAnchor anchor; if (type.equals(ExcelType.HSSF)) { anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); } else { anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1); }
可以看到,在创建图片插入位置的时候已经指定了图片的跨度为1行1列,即左上角的单元格。如果之前又设置了RowSpan或者ColumnSpan,那么图片高度的设置也会失效,最终导致导出的图片非常小。
搜索Java知音公众号,回复“后端面试”,送你一份Java面试题宝典.pdf
个人认为ImageEntity提供的RowSpan或者ColumnSpan的set方法并没有什么用,因为我们动态创建的合并单元格并不能被赋值。所以,导出图片的最好方式就是直接指定它的高度,因为宽度会自动填充单元格,模板中单元格的宽度要合适。
//ExcelExportOfTemplateUtil.java if (img.getRowspan()>1 || img.getColspan() > 1){ img.setHeight(0); PoiMergeCellUtil.addMergedRegion(cell.getSheet(),cell.getRowIndex(), cell.getRowIndex() + img.getRowspan() - 1, cell.getColumnIndex(), cell.getColumnIndex() + img.getColspan() -1); }
将数据导出至模板
以上准备工作全部完成后就可以将模板和数据进行组装了,或者说是渲染,代码如下所示:
public static void exportByTemplate(String templateName, Map<String, Object> data, OutputStream fileOut) { TemplateExportParams params = new TemplateExportParams("export/template/" + templateName, true); try { Workbook workbook = ExcelExportUtil.exportExcel(params, data); workbook.write(fileOut); } catch (Exception e) { LogUtil.error("", e); } }
总结
网上针对EasyPOI的介绍多限于最基本的行插入功能,但实际上Excel模板的需求可能各式各样。本文只是抛砖引玉,对EasyPOI中的部分概念做了详细介绍,希望帮助大家少踩坑。
如果想详细了解EasyPOI的各种功能,参考链接中的文档说明及测试项目源码就是最好的学习资料。希望大家都能得心应手地使用EasyPOI,大大提升开发效率!
参考链接
EasyPOI官方文档
https://opensource.afterturn.cn/doc/easypoi.html
EasyPOI测试项目
https://gitee.com/lemur/easypoi-test
一些坑
近日有网友求助我解决EasyPOI的复杂模板配置问题,通过解决该网友的问题发现了EasyPOI中的几个坑点,补充说明几个问题。
Comment configurer des modèles complexes pris en charge par EasyPOI a été décrit dans la section Analyse de la conception de modèles complexes. La configuration de ce modèle est tout à fait correcte, mais il y a trois points qui ne sont pas clairement énoncés, et il est facile pour tout le monde de se tromper en copiant la gourde :
{{!fe : la liste doit être dans un document séparé colonne. Dans le code source d'EasyPOI, le nombre de lignes requises pour chaque élément de la liste est déterminé en fonction de l'étendue des lignes et des colonnes de la cellule. Par exemple, dans l'image ci-dessus, l'étendue de la cellule est de 5 lignes et 1 colonne. En d'autres termes, chaque élément de la liste occupera 5 lignes à l'avenir. Si vous estimez que cette colonne n'est pas conforme au style du modèle personnalisé, vous pouvez définir la largeur de la colonne sur 0, mais vous devez avoir {{!fe: list. Il ne peut y avoir de cellules vides entre les symboles de début et de fin {{}} de l'objet ! Le code lancera directement une exception lorsqu'il analysera que la cellule est vide. Si vous voulez que la cellule soit vide, vous devez écrire une chaîne vide : ''''. Caractère de saut de ligne]] doit occuper la dernière cellule de chaque ligne ! Par exemple, s'il y a 10 cellules dans la première ligne et que seules les 5 premières sont utilisées dans la deuxième ligne, vous ne pouvez pas écrire directement le caractère de saut de ligne ]] à la fin de la 5ème. Au lieu de cela, vous devez en fusionner 6. -10 cellules puis écrivez enter]]. Reportez-vous à la dernière colonne de la ligne de date de production dans l'image ci-dessus. La raison de ce paramètre est qu'EasyPOI exige que le nombre de cellules dans chaque ligne soit exactement le même, car l'étendue des colonnes de chaque cellule est déterminée dans le code source. Si le caractère de saut de ligne ]] est utilisé à l'avance, le nombre. Les colonnes seront différentes des autres lignes, cela sera alors gâché lors de l'attribution de valeurs et des exceptions d'index se produiront.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Cet article vous guidera tout au long du processus de création d'une chronologie pour les tables et graphiques de pivot Excel et montrera comment vous pouvez l'utiliser pour interagir avec vos données de manière dynamique et engageante. Vous avez organisé vos données dans un pivo

Ce didacticiel montre comment localiser efficacement les n valeurs supérieures dans un ensemble de données et récupérer les données associées à l'aide de formules Excel. Que vous ayez besoin des critères les plus élevés, les plus bas ou les plus élevés, ce guide fournit des solutions. Findi

Master Google Sheets Tri: un guide complet Le tri des données dans Google Sheets n'a pas besoin d'être complexe. Ce guide couvre diverses techniques, du tri des feuilles entières à des gammes spécifiques, par couleur, date et plusieurs colonnes. Que vous soyez un novi

Dans ce tutoriel, vous apprendrez à utiliser des expressions régulières dans Excel pour trouver et extraire des sous-chaînes correspondant à un modèle donné. Microsoft Excel fournit un certain nombre de fonctions pour extraire du texte des cellules. Ces fonctions peuvent faire face à la plupart

Ce guide vous montre deux façons faciles d'activer les modèles de messagerie dans Gmail: utiliser les paramètres intégrés de Gmail ou installer les modèles de messagerie partagés pour l'extension Gmail Chrome. Les modèles Gmail sont un énorme gain de temps pour les e-mails fréquemment envoyés, éliminant

Ce didacticiel vous montre comment ajouter des listes déroulantes à vos modèles de messagerie Outlook, y compris plusieurs sélections et population de bases de données. Bien que Outlook ne prenne pas directement en charge les listes déroulantes, ce guide fournit des solutions créatives. Modèles de messagerie SAV

Ne serait-il pas pratique si vous pouviez composer un e-mail maintenant et l'avoir envoyé plus tard et plus opportun? Avec la fonction de planification d'Outlook, vous pouvez faire exactement cela! Imaginez que vous travaillez tard dans la nuit, inspiré par un IDE brillant

Ce tutoriel montre plusieurs méthodes de séparation du texte et des nombres dans les cellules Excel, en utilisant à la fois des fonctions intégrées et des fonctions VBA personnalisées. Vous apprendrez à extraire les nombres tout en supprimant le texte, isolez le texte tout en jetant les nombres
