Heim > Themen > excel > Hauptteil

Mit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren

Freigeben: 2023-07-26 16:32:18
nach vorne
2145 Leute haben es durchsucht

Vorwort

Kürzlich stellte ein Leser Fragen zu easypoi, also habe ich mir die Zeit genommen, einen Artikel zusammenzustellen.

Text

Die Funktion von EasyPOI ist genau wie der Name Easy. Die Hauptfunktion ist Leichtigkeit, sodass eine Person, die noch nie mit POI in Berührung gekommen ist, problemlos Excel-Export, Excel-Vorlagenexport, Excel-Import und Word schreiben kann Vorlagenexport. Durch einfache Anmerkungen und Vorlagensprache (vertraute Ausdruckssyntax) werden bisher komplexe Schreibmethoden vervollständigt.

Dieser Artikel verwendet hauptsächlich einfache Analysen, um den Lesern zu zeigen, wie sie Excel-Vorlagen schreiben und wie sie mit EasyPOI Excel-Daten exportieren können, die ihren Anforderungen entsprechen, wodurch die Codierung vereinfacht wird. Gleichzeitig werden in diesem Artikel auch einige ungewöhnliche Funktionen wie die Bildexportfunktion erläutert, damit der Leser Fallstricke vermeiden kann.

Versions- und Abhängigkeitsanweisungen

EasyPOI4.0.0 und spätere Versionen hängen von Apache POI 4.0.0 und späteren Versionen ab. Daher müssen in der Maven-Konfiguration die Versionsnummern der beiden übereinstimmen.

Es ist zu beachten, dass Apache POI 4.0.0 im Vergleich zur Vorgängerversion erhebliche Änderungen aufweist. Wenn der Excel-Operationsteil des Vorgängercodes von der alten Version abhängt, wird die Verwendung von 4.0.0 und späteren Versionen nicht empfohlen. Wenn der vorherige Code die Details zum Erstellen von WorkBook nicht oder nur selten enthält, ist die Verwendung der neuen Version natürlich kein Problem.

Das Projekt, das der Autor neu schreiben muss, basiert auf JEECG Version 3.7 und basiert auf Version 3.9 von Apache POI. Die höchste von JEECG verwaltete Jeasypoi-Version ist nur 2.2.0, und diese Version unterstützt die Funktion zum Exportieren von Vorlagenbildern nicht. Apropos, ich möchte mich über das folgende JEECG-Team beschweren. Da ich nicht vorhabe, jeasypoi zu pflegen, warum nicht einfach das offizielle EasyPOI direkt im Projekt verwenden? Wie viele Gruben hat die Version 2.2.0 für Entwickler gegraben? ?

Um mit der alten Version kompatibel zu sein und die von EasyPOI bereitgestellte Bildexportfunktion verwenden zu können, habe ich schließlich die EasyPOI-Version 3.3.0 übernommen und die entsprechende Apache POI-Abhängigkeit ist 3.15.

Maven-Konfiguration ist wie folgt:

<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>
Nach dem Login kopieren

Excel-Vorlagendesign

Wir verwenden die Vorlagenexportfunktion von EasyPOI, weil wir den Stil des Excel-Berichts nicht durch Codierung entwerfen möchten, also das erste Der Arbeitsschritt besteht darin, die Excel-Vorlage zu entwerfen und klar zu unterscheiden, welche Teile fixiert sind und welche Teile in einer Schleife ausgefüllt werden müssen. EasyPOI verfügt über eine eigene Ausdruckssprache. Eine detaillierte Einführung zu jedem Ausdruck finden Sie unter dem Referenzlink unten.

Eine einfache Excel-Berichtsvorlage

Einige einfache Vorlagen werden hier nicht im Detail erläutert, es werden nur die Renderings und der Inhalt der Vorlagenkonfiguration angezeigt. Wenn die Leser verstehen, wie man komplexe Vorlagen erstellt und Werte eingibt, werden einfache Vorlagen schnell verstanden.

Schauen Sie sich zunächst die Berichtsdarstellungen an:

Mit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren

Dann schauen Sie sich die eigentliche Vorlage an:

Mit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren

Haben Sie nach dem Betrachten der beiden Bilder oben bereits die Leistungsfähigkeit der Vorlagenexportfunktion gespürt? „Eine komplexe Excel-Berichtsvorlage.“ the way Eine kurze Einführung in einige Ausdrücke von EasyPOI.

Schauen wir uns zuerst die Darstellungen an: Dann schauen Sie sich die Vorlage an:

Haben Sie beim Vergleich dieser beiden Bilder das Gefühl, dass Wissen Ihr Schicksal verändern kann?

Mit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren

Analyse des komplexen Vorlagendesigns

Mit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren

Anhand der Vorlagenbilder und Darstellungen der Produktinformationen haben wir festgestellt, dass die gesamte Vorlage tatsächlich in einen oberen und einen unteren Teil unterteilt ist. Im oberen Teil handelt es sich um die unveränderten Kopfinformationen und im unteren Teil um die zyklisch eingefügten Produktdetailinformationen. Daher liegt unser Fokus in der zweiten Hälfte auf der Grammatik.

Die erste Spalte in der unteren Hälfte des Bildes wird nicht vollständig angezeigt, es handelt sich tatsächlich um {{!fe: list t.id. Hinweis: Hier gibt es kein }}-Symbol! Laut der offiziellen Dokumentation von EasyPOI stellt {{}} einen Ausdruck dar und der darin enthaltene Wert wird basierend auf dem Ausdruck ermittelt. Wenn Sie sich das Bild genau ansehen, können Sie feststellen, dass das Schlusssymbol {{}} des Ausdrucks in der unteren rechten Ecke des Bildes erscheint. Das heißt, beginnend mit der ersten Spalte {{ und endend in der unteren rechten Ecke}} ist alles dazwischen Teil des Ausdrucks.

Da die gesamten Vorlageninformationen Teil des Ausdrucks sind, müssen auch gewöhnliche Zeichenfolgen speziell gekennzeichnet werden. Die Unterausdrücke im Ausdruck werden im Folgenden einzeln erläutert.

!fe: Daten durchlaufen, ohne Zeilen zu erstellen.

Dieser Satz im offiziellen Dokument kann für jeden etwas verwirrend sein. Was bedeutet es, keinen Streit zu verursachen? Tatsächlich ist das Nichterstellen einer Zeile relativ zum Erstellen einer Zeile, und der Ausdruck zum Erstellen einer Zeile lautet fe:.

So wie jeder Datensatz in der Datenbank einem Entitätsobjekt entspricht, bedeutet das Erstellen einer Zeile, dass jede Zeile ein Entitätsobjekt ist. Die Attribute dieses Entitätsobjekts werden mit {{}}-Ausdrücken umschlossen.

Wenn keine Zeile erstellt wird, gibt es im gesamten Ausdruck nur ein Entitätsobjekt, dieses Objekt ist jedoch etwas Besonderes. Es wird durch N Entitäten in der Liste zusammengefügt. Jede Entität bezieht sich nicht nur auf das Modell selbst, sondern enthält auch den Excel-Stil, z. B. wie viele Zellen sie einnimmt, die Koordinaten der Zellen, die Anordnungsreihenfolge usw.

list ist ein benutzerdefinierter Name, der die Datensammlung im Ausdruck darstellt. Der Code verwendet list als Schlüssel, um die Sammlung von Werten aus Map zu erhalten.

Die Namensliste ist leicht verständlich. Sie ist lediglich ein Platzhalter und kann frei gewählt werden. Wenn EasyPOI die Liste analysiert, weiß es, dass es eine Reihe von Werten des Schlüssels in Map gibt. Wenn es die Daten später analysiert, kann es diese einfach aus der Menge übernehmen.

Durchsuchen Sie das offizielle Konto von Java Zhiyin, antworten Sie auf „Backend-Interview“ und wir geben Ihnen einen Java-Interview-Fragenleitfaden.pdf

t Vordefinierter Wert, der jedes Objekt in der Sammlung darstellt.

Aus der Vorlage können wir ungefähr ersehen, dass jedes Objekt in der Liste t heißt und t.name das Namensattribut von t darstellt, sodass der Name t beiläufig aufgerufen werden kann. Wie auch immer, es ist dasselbe wie list, und es fungiert als Platzhalter.

Aber eigentlich ist das eine große Grube! Wenn Sie t durch einen anderen Wert wie g ersetzen, g.name g.code usw. an anderer Stelle in der Vorlage schreiben, wird es letztendlich nicht geparst! Die offizielle Dokumentation betont diesen Punkt nicht, aber der Autor hat ihn erst entdeckt, nachdem er tatsächlich in die Falle getreten ist!

]] Newline-Zeichen Export mit mehrzeiligem Durchlauf.

Die offizielle Erklärung dieses Symbols ist ebenfalls verwirrend. Was ist ein Zeilenumbruch und -export? Tatsächlich bedeutet dies, dass, wenn der Ausdruck dieses Symbol enthält, der Inhalt nach der Zeile nicht analysiert wird, unabhängig davon, ob sich dahinter ein anderer Inhalt oder Stil befindet.

Dieses Symbol muss in die letzte Spalte jeder Zeile geschrieben werden, da sonst die Anzahl der Zeilen und Spalten unterschiedlich ist und eine Nullzeiger-Ausnahme gemeldet wird, wenn EasyPOI eine interne Zuweisung durchführt.

‘‘ Einfache Anführungszeichen stellen konstante Werte dar‘‘ Zum Beispiel ‚1‘, dann ist die Ausgabe 1

Die Einführung hier in der offiziellen Dokumentation hat auch Fallstricke. '' bedeutet einen konstanten Wert, aber tatsächlich ist es falsch, dies nur in Excel zu haben, denn wenn Excel in einer Zelle auf ' trifft, geht es davon aus, dass es sich bei den folgenden Werten ausschließlich um Zeichenfolgen handelt, sodass Sie '' Bibliothekstyp: ' hineinschreiben müssen die Zelle, sodass „Bibliothekstyp:“ angezeigt wird, nicht die Zeichenfolge „Bibliothekstyp:“.

Nach der obigen Analyse ähnelt die Vorlage im Bild tatsächlich der folgenden:

{{!fe: list t.id ‘库别:’ t.bin 换行 ‘商品名称:’ t.name 换行 ‘商品编号:’ t.code t.barcode 换行 ‘生产日期:’ t.proDate 换行 ‘进货日期:’ t.recvDate}}

如果list中有多条记录,上述字符串就再循环拼接一些内容,最终都在一个{{}}表达式中。

至此,模板的设计已剖析完毕,读者可根据自己的需求结合官方文档自行设计模板。下面将对模板赋值进行介绍。

准备模板数据

从上节的描述中可知,只需要准备一个Map的对象即可,其中键为list,值为一个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);
Nach dem Login kopieren

图片数据导出

上述代码中需要特殊关注的是图片导出部分。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);
}
Nach dem Login kopieren

可以看到,在创建图片插入位置的时候已经指定了图片的跨度为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);
}
Nach dem Login kopieren

将数据导出至模板

以上准备工作全部完成后就可以将模板和数据进行组装了,或者说是渲染,代码如下所示:

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);
    }
}
Nach dem Login kopieren

总结

网上针对EasyPOI的介绍多限于最基本的行插入功能,但实际上Excel模板的需求可能各式各样。本文只是抛砖引玉,对EasyPOI中的部分概念做了详细介绍,希望帮助大家少踩坑。

如果想详细了解EasyPOI的各种功能,参考链接中的文档说明及测试项目源码就是最好的学习资料。希望大家都能得心应手地使用EasyPOI,大大提升开发效率!

参考链接

EasyPOI官方文档

  • https://opensource.afterturn.cn/doc/easypoi.html

EasyPOI测试项目

  • https://gitee.com/lemur/easypoi-test

一些坑

近日有网友求助我解决EasyPOI的复杂模板配置问题,通过解决该网友的问题发现了EasyPOI中的几个坑点,补充说明几个问题。

Wie Sie komplexe Vorlagen konfigurieren, die von EasyPOI unterstützt werden, wurde im Abschnitt „Analyse komplexer Vorlagendesigns“ beschrieben. Die Konfiguration dieser Vorlage ist absolut korrekt, es gibt jedoch drei Punkte, die nicht klar angegeben sind, und es ist leicht, dass jeder beim Kopieren des Kürbisses Fehler macht:

  1. {{!fe: Liste muss in einer separaten sein Spalte. Im EasyPOI-Quellcode wird die Anzahl der für jedes Element in der Liste erforderlichen Zeilen basierend auf der Zeilen- und Spaltenspanne der Zelle bestimmt. Im obigen Bild beträgt die Spanne der Zelle beispielsweise 5 Zeilen und 1 Spalte. Mit anderen Worten: Jedes Element in der Liste wird in Zukunft 5 Zeilen belegen. Wenn Sie der Meinung sind, dass diese Spalte nicht dem Stil der benutzerdefinierten Vorlage entspricht, können Sie die Spaltenbreite der Spalte auf 0 setzen, Sie müssen jedoch über {{!fe: list.
  2. Zwischen dem Start- und Endsymbol {{}} des Objekts dürfen keine leeren Zellen vorhanden sein! Der Code löst direkt eine Ausnahme aus, wenn er analysiert, dass die Zelle leer ist. Wenn Sie möchten, dass die Zelle leer ist, müssen Sie eine leere Zeichenfolge schreiben: ''''.
  3. Zeilenumbruchzeichen]] muss die letzte Zelle jeder Zeile einnehmen! Wenn sich beispielsweise in der ersten Zeile 10 Zellen befinden und in der zweiten Zeile nur die ersten 5 verwendet werden, können Sie das Zeilenumbruchzeichen ]] nicht direkt am Ende der 5. Zeile schreiben. Stattdessen müssen Sie 6 zusammenführen -10 Zellen und schreiben Sie dann Enter]]. Beachten Sie die letzte Spalte der Zeile mit dem Produktionsdatum im Bild oben. Der Grund für diese Einstellung ist, dass EasyPOI eine exakt gleiche Anzahl von Zellen in jeder Zeile erfordert, da der Spaltenumfang jeder Zelle im Quellcode festgelegt wird. Bei Verwendung des Zeilenumbruchzeichens ]] wird die Anzahl festgelegt Wenn sich die Anzahl der Spalten von denen anderer Zeilen unterscheidet, kommt es beim Zuweisen von Werten zu Problemen und es treten Indexausnahmen auf.

Das obige ist der detaillierte Inhalt vonMit EasyPOI elegant Excel-Vorlagendaten (einschließlich Bilder) exportieren. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:Java学习指南
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!