├── .gitignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── README.md ├── mvnw ├── mvnw.cmd ├── pom.xml └── src └── main ├── java └── com │ └── jiashn │ └── generateReport │ ├── GenerateReportApplication.java │ ├── controller │ └── ApachePoitlController.java │ ├── domain │ ├── ChartSeriesRenderData.java │ ├── LabelData.java │ ├── ListRenderData.java │ ├── PictureContentData.java │ ├── TableSeriesRenderData.java │ └── TextContentData.java │ ├── enums │ ├── CharCombinationType.java │ ├── PicTypeEnum.java │ └── WordContentTypeEnum.java │ ├── factory │ └── GenerateWordFactory.java │ ├── realize │ ├── ChartGenerateWord.java │ ├── ListGenerateWord.java │ ├── PictureGenerateWord.java │ ├── TableGenerateWord.java │ └── TextGenerateWord.java │ ├── service │ ├── ApachePoitlService.java │ ├── GenerateWord.java │ └── impl │ │ └── ApachePoitlServiceImpl.java │ └── util │ └── OperateWordManage.java └── resources ├── application.yml └── static └── template └── demo_template.docx /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovejiashn/generate_report/c43a73ac5cf94ba68c2a2daad28c81c3992934a4/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one 2 | # or more contributor license agreements. See the NOTICE file 3 | # distributed with this work for additional information 4 | # regarding copyright ownership. The ASF licenses this file 5 | # to you under the Apache License, Version 2.0 (the 6 | # "License"); you may not use this file except in compliance 7 | # with the License. You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, 12 | # software distributed under the License is distributed on an 13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 | # KIND, either express or implied. See the License for the 15 | # specific language governing permissions and limitations 16 | # under the License. 17 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.7/apache-maven-3.8.7-bin.zip 18 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # generate_report 2 | 基于poi-tl生成word文件报表 3 | 4 | 使用poi-tl进行简单封装,完成word报表生成 5 | -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # https://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /usr/local/etc/mavenrc ] ; then 40 | . /usr/local/etc/mavenrc 41 | fi 42 | 43 | if [ -f /etc/mavenrc ] ; then 44 | . /etc/mavenrc 45 | fi 46 | 47 | if [ -f "$HOME/.mavenrc" ] ; then 48 | . "$HOME/.mavenrc" 49 | fi 50 | 51 | fi 52 | 53 | # OS specific support. $var _must_ be set to either true or false. 54 | cygwin=false; 55 | darwin=false; 56 | mingw=false 57 | case "`uname`" in 58 | CYGWIN*) cygwin=true ;; 59 | MINGW*) mingw=true;; 60 | Darwin*) darwin=true 61 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 62 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 63 | if [ -z "$JAVA_HOME" ]; then 64 | if [ -x "/usr/libexec/java_home" ]; then 65 | export JAVA_HOME="`/usr/libexec/java_home`" 66 | else 67 | export JAVA_HOME="/Library/Java/Home" 68 | fi 69 | fi 70 | ;; 71 | esac 72 | 73 | if [ -z "$JAVA_HOME" ] ; then 74 | if [ -r /etc/gentoo-release ] ; then 75 | JAVA_HOME=`java-config --jre-home` 76 | fi 77 | fi 78 | 79 | if [ -z "$M2_HOME" ] ; then 80 | ## resolve links - $0 may be a link to maven's home 81 | PRG="$0" 82 | 83 | # need this for relative symlinks 84 | while [ -h "$PRG" ] ; do 85 | ls=`ls -ld "$PRG"` 86 | link=`expr "$ls" : '.*-> \(.*\)$'` 87 | if expr "$link" : '/.*' > /dev/null; then 88 | PRG="$link" 89 | else 90 | PRG="`dirname "$PRG"`/$link" 91 | fi 92 | done 93 | 94 | saveddir=`pwd` 95 | 96 | M2_HOME=`dirname "$PRG"`/.. 97 | 98 | # make it fully qualified 99 | M2_HOME=`cd "$M2_HOME" && pwd` 100 | 101 | cd "$saveddir" 102 | # echo Using m2 at $M2_HOME 103 | fi 104 | 105 | # For Cygwin, ensure paths are in UNIX format before anything is touched 106 | if $cygwin ; then 107 | [ -n "$M2_HOME" ] && 108 | M2_HOME=`cygpath --unix "$M2_HOME"` 109 | [ -n "$JAVA_HOME" ] && 110 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 111 | [ -n "$CLASSPATH" ] && 112 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 113 | fi 114 | 115 | # For Mingw, ensure paths are in UNIX format before anything is touched 116 | if $mingw ; then 117 | [ -n "$M2_HOME" ] && 118 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 119 | [ -n "$JAVA_HOME" ] && 120 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 121 | fi 122 | 123 | if [ -z "$JAVA_HOME" ]; then 124 | javaExecutable="`which javac`" 125 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 126 | # readlink(1) is not available as standard on Solaris 10. 127 | readLink=`which readlink` 128 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 129 | if $darwin ; then 130 | javaHome="`dirname \"$javaExecutable\"`" 131 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 132 | else 133 | javaExecutable="`readlink -f \"$javaExecutable\"`" 134 | fi 135 | javaHome="`dirname \"$javaExecutable\"`" 136 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 137 | JAVA_HOME="$javaHome" 138 | export JAVA_HOME 139 | fi 140 | fi 141 | fi 142 | 143 | if [ -z "$JAVACMD" ] ; then 144 | if [ -n "$JAVA_HOME" ] ; then 145 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 146 | # IBM's JDK on AIX uses strange locations for the executables 147 | JAVACMD="$JAVA_HOME/jre/sh/java" 148 | else 149 | JAVACMD="$JAVA_HOME/bin/java" 150 | fi 151 | else 152 | JAVACMD="`\\unset -f command; \\command -v java`" 153 | fi 154 | fi 155 | 156 | if [ ! -x "$JAVACMD" ] ; then 157 | echo "Error: JAVA_HOME is not defined correctly." >&2 158 | echo " We cannot execute $JAVACMD" >&2 159 | exit 1 160 | fi 161 | 162 | if [ -z "$JAVA_HOME" ] ; then 163 | echo "Warning: JAVA_HOME environment variable is not set." 164 | fi 165 | 166 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 167 | 168 | # traverses directory structure from process work directory to filesystem root 169 | # first directory with .mvn subdirectory is considered project base directory 170 | find_maven_basedir() { 171 | 172 | if [ -z "$1" ] 173 | then 174 | echo "Path not specified to find_maven_basedir" 175 | return 1 176 | fi 177 | 178 | basedir="$1" 179 | wdir="$1" 180 | while [ "$wdir" != '/' ] ; do 181 | if [ -d "$wdir"/.mvn ] ; then 182 | basedir=$wdir 183 | break 184 | fi 185 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 186 | if [ -d "${wdir}" ]; then 187 | wdir=`cd "$wdir/.."; pwd` 188 | fi 189 | # end of workaround 190 | done 191 | echo "${basedir}" 192 | } 193 | 194 | # concatenates all lines of a file 195 | concat_lines() { 196 | if [ -f "$1" ]; then 197 | echo "$(tr -s '\n' ' ' < "$1")" 198 | fi 199 | } 200 | 201 | BASE_DIR=`find_maven_basedir "$(pwd)"` 202 | if [ -z "$BASE_DIR" ]; then 203 | exit 1; 204 | fi 205 | 206 | ########################################################################################## 207 | # Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 208 | # This allows using the maven wrapper in projects that prohibit checking in binary data. 209 | ########################################################################################## 210 | if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then 211 | if [ "$MVNW_VERBOSE" = true ]; then 212 | echo "Found .mvn/wrapper/maven-wrapper.jar" 213 | fi 214 | else 215 | if [ "$MVNW_VERBOSE" = true ]; then 216 | echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." 217 | fi 218 | if [ -n "$MVNW_REPOURL" ]; then 219 | jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 220 | else 221 | jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 222 | fi 223 | while IFS="=" read key value; do 224 | case "$key" in (wrapperUrl) jarUrl="$value"; break ;; 225 | esac 226 | done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" 227 | if [ "$MVNW_VERBOSE" = true ]; then 228 | echo "Downloading from: $jarUrl" 229 | fi 230 | wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" 231 | if $cygwin; then 232 | wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` 233 | fi 234 | 235 | if command -v wget > /dev/null; then 236 | if [ "$MVNW_VERBOSE" = true ]; then 237 | echo "Found wget ... using wget" 238 | fi 239 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 240 | wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 241 | else 242 | wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" 243 | fi 244 | elif command -v curl > /dev/null; then 245 | if [ "$MVNW_VERBOSE" = true ]; then 246 | echo "Found curl ... using curl" 247 | fi 248 | if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then 249 | curl -o "$wrapperJarPath" "$jarUrl" -f 250 | else 251 | curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f 252 | fi 253 | 254 | else 255 | if [ "$MVNW_VERBOSE" = true ]; then 256 | echo "Falling back to using Java to download" 257 | fi 258 | javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" 259 | # For Cygwin, switch paths to Windows format before running javac 260 | if $cygwin; then 261 | javaClass=`cygpath --path --windows "$javaClass"` 262 | fi 263 | if [ -e "$javaClass" ]; then 264 | if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 265 | if [ "$MVNW_VERBOSE" = true ]; then 266 | echo " - Compiling MavenWrapperDownloader.java ..." 267 | fi 268 | # Compiling the Java class 269 | ("$JAVA_HOME/bin/javac" "$javaClass") 270 | fi 271 | if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then 272 | # Running the downloader 273 | if [ "$MVNW_VERBOSE" = true ]; then 274 | echo " - Running MavenWrapperDownloader.java ..." 275 | fi 276 | ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") 277 | fi 278 | fi 279 | fi 280 | fi 281 | ########################################################################################## 282 | # End of extension 283 | ########################################################################################## 284 | 285 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 286 | if [ "$MVNW_VERBOSE" = true ]; then 287 | echo $MAVEN_PROJECTBASEDIR 288 | fi 289 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 290 | 291 | # For Cygwin, switch paths to Windows format before running java 292 | if $cygwin; then 293 | [ -n "$M2_HOME" ] && 294 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 295 | [ -n "$JAVA_HOME" ] && 296 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 297 | [ -n "$CLASSPATH" ] && 298 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 299 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 300 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 301 | fi 302 | 303 | # Provide a "standardized" way to retrieve the CLI args that will 304 | # work with both Windows and non-Windows executions. 305 | MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" 306 | export MAVEN_CMD_LINE_ARGS 307 | 308 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 309 | 310 | exec "$JAVACMD" \ 311 | $MAVEN_OPTS \ 312 | $MAVEN_DEBUG_OPTS \ 313 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 314 | "-Dmaven.home=${M2_HOME}" \ 315 | "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 316 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 317 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM https://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM set title of command window 39 | title %0 40 | @REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' 41 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 42 | 43 | @REM set %HOME% to equivalent of $HOME 44 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 45 | 46 | @REM Execute a user defined script before this one 47 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 48 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 49 | if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* 50 | if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %* 51 | :skipRcPre 52 | 53 | @setlocal 54 | 55 | set ERROR_CODE=0 56 | 57 | @REM To isolate internal variables from possible post scripts, we use another setlocal 58 | @setlocal 59 | 60 | @REM ==== START VALIDATION ==== 61 | if not "%JAVA_HOME%" == "" goto OkJHome 62 | 63 | echo. 64 | echo Error: JAVA_HOME not found in your environment. >&2 65 | echo Please set the JAVA_HOME variable in your environment to match the >&2 66 | echo location of your Java installation. >&2 67 | echo. 68 | goto error 69 | 70 | :OkJHome 71 | if exist "%JAVA_HOME%\bin\java.exe" goto init 72 | 73 | echo. 74 | echo Error: JAVA_HOME is set to an invalid directory. >&2 75 | echo JAVA_HOME = "%JAVA_HOME%" >&2 76 | echo Please set the JAVA_HOME variable in your environment to match the >&2 77 | echo location of your Java installation. >&2 78 | echo. 79 | goto error 80 | 81 | @REM ==== END VALIDATION ==== 82 | 83 | :init 84 | 85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 86 | @REM Fallback to current working directory if not found. 87 | 88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 90 | 91 | set EXEC_DIR=%CD% 92 | set WDIR=%EXEC_DIR% 93 | :findBaseDir 94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 95 | cd .. 96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 97 | set WDIR=%CD% 98 | goto findBaseDir 99 | 100 | :baseDirFound 101 | set MAVEN_PROJECTBASEDIR=%WDIR% 102 | cd "%EXEC_DIR%" 103 | goto endDetectBaseDir 104 | 105 | :baseDirNotFound 106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 107 | cd "%EXEC_DIR%" 108 | 109 | :endDetectBaseDir 110 | 111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 112 | 113 | @setlocal EnableExtensions EnableDelayedExpansion 114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 116 | 117 | :endReadAdditionalConfig 118 | 119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 120 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 121 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 122 | 123 | set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 124 | 125 | FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( 126 | IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B 127 | ) 128 | 129 | @REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central 130 | @REM This allows using the maven wrapper in projects that prohibit checking in binary data. 131 | if exist %WRAPPER_JAR% ( 132 | if "%MVNW_VERBOSE%" == "true" ( 133 | echo Found %WRAPPER_JAR% 134 | ) 135 | ) else ( 136 | if not "%MVNW_REPOURL%" == "" ( 137 | SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar" 138 | ) 139 | if "%MVNW_VERBOSE%" == "true" ( 140 | echo Couldn't find %WRAPPER_JAR%, downloading it ... 141 | echo Downloading from: %DOWNLOAD_URL% 142 | ) 143 | 144 | powershell -Command "&{"^ 145 | "$webclient = new-object System.Net.WebClient;"^ 146 | "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ 147 | "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ 148 | "}"^ 149 | "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ 150 | "}" 151 | if "%MVNW_VERBOSE%" == "true" ( 152 | echo Finished downloading %WRAPPER_JAR% 153 | ) 154 | ) 155 | @REM End of extension 156 | 157 | @REM Provide a "standardized" way to retrieve the CLI args that will 158 | @REM work with both Windows and non-Windows executions. 159 | set MAVEN_CMD_LINE_ARGS=%* 160 | 161 | %MAVEN_JAVA_EXE% ^ 162 | %JVM_CONFIG_MAVEN_PROPS% ^ 163 | %MAVEN_OPTS% ^ 164 | %MAVEN_DEBUG_OPTS% ^ 165 | -classpath %WRAPPER_JAR% ^ 166 | "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ 167 | %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 168 | if ERRORLEVEL 1 goto error 169 | goto end 170 | 171 | :error 172 | set ERROR_CODE=1 173 | 174 | :end 175 | @endlocal & set ERROR_CODE=%ERROR_CODE% 176 | 177 | if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost 178 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 179 | if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" 180 | if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd" 181 | :skipRcPost 182 | 183 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 184 | if "%MAVEN_BATCH_PAUSE%"=="on" pause 185 | 186 | if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE% 187 | 188 | cmd /C exit /B %ERROR_CODE% 189 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.4.8 9 | 10 | 11 | com.jiashn 12 | generate_report 13 | 0.0.1-SNAPSHOT 14 | generate_report 15 | use poi-tl generate report 16 | 17 | 1.8 18 | 2.6 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-web 24 | 25 | 26 | 27 | org.projectlombok 28 | lombok 29 | true 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-test 34 | test 35 | 36 | 37 | 38 | com.deepoove 39 | poi-tl 40 | 1.8.2 41 | 42 | 43 | 44 | commons-io 45 | commons-io 46 | ${commonIo.version} 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-maven-plugin 55 | 56 | 57 | 58 | org.projectlombok 59 | lombok 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/GenerateReportApplication.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | @SpringBootApplication 7 | public class GenerateReportApplication { 8 | 9 | public static void main(String[] args) { 10 | SpringApplication.run(GenerateReportApplication.class, args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/controller/ApachePoitlController.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.controller; 2 | 3 | import com.jiashn.generateReport.service.ApachePoitlService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * @author: jiangjs 11 | * @description: Poi-tl生成图表 12 | * @date: 2022/11/23 17:08 13 | **/ 14 | @RestController 15 | @RequestMapping("/poitl") 16 | public class ApachePoitlController { 17 | 18 | @Autowired 19 | private ApachePoitlService poitlService; 20 | 21 | @GetMapping("/generateCharts.do") 22 | public void generateCharts(){ 23 | poitlService.generateCharts(); 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/ChartSeriesRenderData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.deepoove.poi.data.SeriesRenderData; 4 | import com.jiashn.generateReport.enums.CharCombinationType; 5 | import lombok.Data; 6 | import lombok.EqualsAndHashCode; 7 | import lombok.experimental.Accessors; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author: jiangjs 13 | * @description: 图表 14 | * @date: 2022/11/24 11:38 15 | **/ 16 | @EqualsAndHashCode(callSuper = true) 17 | @Data 18 | @Accessors(chain = true) 19 | public class ChartSeriesRenderData extends com.jiashn.generateReport.domain.LabelData { 20 | /** 21 | * 横轴数据 22 | */ 23 | private String[] categories; 24 | 25 | /** 26 | * 图表名称 27 | */ 28 | private String title; 29 | 30 | /** 31 | * 图表类型 组合 32 | */ 33 | private CharCombinationType charType = CharCombinationType.MULTI; 34 | 35 | /** 36 | * 系列对应数据 37 | */ 38 | private List senderData; 39 | 40 | @Data 41 | public static class RenderData{ 42 | /** 43 | * 系列名称 44 | */ 45 | private String renderTitle; 46 | /** 47 | * 系列对应的数据 48 | */ 49 | private Number[] data; 50 | /** 51 | * 该系列对应生成的图表类型 52 | */ 53 | private SeriesRenderData.ComboType comboType = null; 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/LabelData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 4 | import lombok.Data; 5 | import lombok.experimental.Accessors; 6 | 7 | /** 8 | * @author: jiangjs 9 | * @description: 10 | * @date: 2022/11/24 15:05 11 | **/ 12 | @Data 13 | @Accessors(chain = true) 14 | public class LabelData { 15 | /** 16 | * 标签名称 17 | */ 18 | private String labelName; 19 | /** 20 | * 文件内容类型 21 | */ 22 | private WordContentTypeEnum typeEnum; 23 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/ListRenderData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.deepoove.poi.data.NumbericRenderData; 4 | import com.deepoove.poi.data.TextRenderData; 5 | import com.jiashn.generateReport.domain.LabelData; 6 | import com.jiashn.generateReport.domain.LabelData; 7 | import lombok.Data; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.experimental.Accessors; 10 | import org.apache.commons.lang3.tuple.Pair; 11 | import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * @author: jiangjs 17 | * @description: 列表 18 | * @date: 2023/6/2 15:46 19 | **/ 20 | @EqualsAndHashCode(callSuper = true) 21 | @Data 22 | @Accessors(chain = true) 23 | public class ListRenderData extends LabelData { 24 | /** 25 | * 列表数据集 26 | */ 27 | private List list; 28 | 29 | /** 30 | * 列表样式,支持罗马字符、有序无序等,默认为点 31 | */ 32 | private Pair pair = NumbericRenderData.FMT_BULLET; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/PictureContentData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.jiashn.generateReport.enums.PicTypeEnum; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | import lombok.experimental.Accessors; 7 | 8 | import java.io.File; 9 | 10 | /** 11 | * @author: jiangjs 12 | * @description: 图片 13 | * @date: 2022/11/24 16:34 14 | **/ 15 | @EqualsAndHashCode(callSuper = true) 16 | @Data 17 | @Accessors(chain = true) 18 | public class PictureContentData extends LabelData { 19 | /** 20 | * 图片宽度 21 | */ 22 | private Integer width; 23 | /** 24 | * 图片高度 25 | */ 26 | private Integer height; 27 | /** 28 | * 图片类型 29 | */ 30 | private PicTypeEnum picType; 31 | /** 32 | * 图片地址(网络图片插入时使用) 33 | */ 34 | private String picUrl; 35 | /** 36 | * 图片文件 37 | */ 38 | private File file; 39 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/TableSeriesRenderData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.deepoove.poi.data.TextRenderData; 4 | import com.jiashn.generateReport.domain.LabelData; 5 | import com.jiashn.generateReport.domain.LabelData; 6 | import lombok.Data; 7 | import lombok.EqualsAndHashCode; 8 | import lombok.experimental.Accessors; 9 | 10 | import java.util.List; 11 | 12 | /** 13 | * @author: jiangjs 14 | * @description: 15 | * @date: 2022/11/24 17:19 16 | **/ 17 | @EqualsAndHashCode(callSuper = true) 18 | @Data 19 | @Accessors(chain = true) 20 | public class TableSeriesRenderData extends LabelData { 21 | 22 | /** 23 | * 表头 24 | */ 25 | private TextRenderData[] header; 26 | /** 27 | * 表内容 28 | */ 29 | private List contents; 30 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/domain/TextContentData.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.domain; 2 | 3 | import com.deepoove.poi.data.HyperLinkTextRenderData; 4 | import com.deepoove.poi.data.TextRenderData; 5 | import com.jiashn.generateReport.domain.LabelData; 6 | import com.jiashn.generateReport.domain.LabelData; 7 | import lombok.Data; 8 | import lombok.EqualsAndHashCode; 9 | import lombok.experimental.Accessors; 10 | 11 | /** 12 | * @author: jiangjs 13 | * @description: 文本 14 | * @date: 2022/11/24 15:07 15 | **/ 16 | @EqualsAndHashCode(callSuper = true) 17 | @Data 18 | @Accessors(chain = true) 19 | public class TextContentData extends LabelData { 20 | 21 | /** 22 | * 纯文本内容 23 | */ 24 | private String content; 25 | /** 26 | * 带样式文本 27 | */ 28 | private TextRenderData renderData; 29 | /** 30 | * 超链接文本 31 | */ 32 | private HyperLinkTextRenderData linkData; 33 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/enums/CharCombinationType.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.enums; 2 | 3 | /** 4 | * @author: jiangjs 5 | * @description: 6 | * @date: 2023/6/2 16:51 7 | **/ 8 | public enum CharCombinationType { 9 | 10 | /** 11 | * 多组合 12 | */ 13 | MULTI("Multi"), 14 | /** 15 | * 单图形 16 | */ 17 | Single("Single"); 18 | 19 | private final String type; 20 | 21 | CharCombinationType(String type){ 22 | this.type = type; 23 | } 24 | public String getType(){ 25 | return type; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/enums/PicTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.enums; 2 | 3 | /** 4 | * @author: jiangjs 5 | * @description: 图片类型 6 | * @date: 2022/11/24 16:50 7 | **/ 8 | public enum PicTypeEnum { 9 | /** 10 | * png图片 11 | */ 12 | PNG(".png"), 13 | /** 14 | * JPG图片 15 | */ 16 | JPG(".jpg"), 17 | /** 18 | * jpeg 19 | */ 20 | JPEG(".jpeg"); 21 | 22 | private final String picName; 23 | 24 | PicTypeEnum(String picName) { 25 | this.picName = picName; 26 | } 27 | 28 | public String getPicName() { 29 | return picName; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/enums/WordContentTypeEnum.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.enums; 2 | 3 | /** 4 | * @author: jiangjs 5 | * @description: 6 | * @date: 2022/11/24 13:44 7 | **/ 8 | public enum WordContentTypeEnum { 9 | /** 10 | * 文本 11 | */ 12 | TEXT, 13 | /** 14 | * 图片 15 | */ 16 | PICTURE, 17 | /** 18 | * 表格 19 | */ 20 | TABLE, 21 | /** 22 | * 列表 23 | */ 24 | LIST, 25 | /** 26 | * 图表 27 | */ 28 | CHART; 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/factory/GenerateWordFactory.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.factory; 2 | 3 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 4 | import com.jiashn.generateReport.service.GenerateWord; 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | import java.util.Objects; 8 | 9 | /** 10 | * @author: jiangjs 11 | * @description: 生成word工厂 12 | * @date: 2022/11/24 14:06 13 | **/ 14 | public class GenerateWordFactory { 15 | 16 | private static final Map TYPE_BACK_DATA = new HashMap<>(); 17 | 18 | public static void register(WordContentTypeEnum typeEnum, GenerateWord word){ 19 | if (Objects.nonNull(typeEnum)){ 20 | TYPE_BACK_DATA.put(typeEnum,word); 21 | } 22 | } 23 | 24 | public static GenerateWord getBackData(WordContentTypeEnum typeEnum){ 25 | return TYPE_BACK_DATA.get(typeEnum); 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/realize/ChartGenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.realize; 2 | 3 | import com.deepoove.poi.data.ChartMultiSeriesRenderData; 4 | import com.deepoove.poi.data.ChartSingleSeriesRenderData; 5 | import com.deepoove.poi.data.SeriesRenderData; 6 | import com.jiashn.generateReport.domain.ChartSeriesRenderData; 7 | import com.jiashn.generateReport.domain.LabelData; 8 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 9 | import com.jiashn.generateReport.factory.GenerateWordFactory; 10 | import com.jiashn.generateReport.service.GenerateWord; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | import java.util.ArrayList; 15 | import java.util.List; 16 | import java.util.Objects; 17 | 18 | /** 19 | * @author: jiangjs 20 | * @description: 图表类型 21 | * @date: 2022/11/24 14:32 22 | **/ 23 | @Component 24 | public class ChartGenerateWord implements GenerateWord { 25 | @PostConstruct 26 | private void init(){ 27 | GenerateWordFactory.register(WordContentTypeEnum.CHART,this); 28 | } 29 | @Override 30 | public Object generateWord(LabelData obj) { 31 | ChartSeriesRenderData renderData = (ChartSeriesRenderData) obj; 32 | if (Objects.nonNull(renderData.getCharType()) && Objects.equals("Single",renderData.getCharType().getType())){ 33 | ChartSingleSeriesRenderData singleSeriesRenderData = new ChartSingleSeriesRenderData(); 34 | singleSeriesRenderData.setCategories(renderData.getCategories()); 35 | singleSeriesRenderData.setChartTitle(renderData.getTitle()); 36 | ChartSeriesRenderData.RenderData seriesData = renderData.getSenderData().get(0); 37 | SeriesRenderData srd = new SeriesRenderData(seriesData.getRenderTitle(),seriesData.getData()); 38 | if (Objects.nonNull(seriesData.getComboType())){ 39 | srd.setComboType(seriesData.getComboType()); 40 | } 41 | singleSeriesRenderData.setSeriesData(srd); 42 | return singleSeriesRenderData; 43 | } else { 44 | ChartMultiSeriesRenderData seriesRenderData = new ChartMultiSeriesRenderData(); 45 | seriesRenderData.setCategories(renderData.getCategories()); 46 | seriesRenderData.setChartTitle(renderData.getTitle()); 47 | List renderDataList = renderData.getSenderData(); 48 | List groupData = new ArrayList<>(); 49 | renderDataList.forEach(data -> { 50 | SeriesRenderData srd = new SeriesRenderData(data.getRenderTitle(),data.getData()); 51 | if (Objects.nonNull(data.getComboType())){ 52 | srd.setComboType(data.getComboType()); 53 | } 54 | groupData.add(srd); 55 | }); 56 | seriesRenderData.setSeriesDatas(groupData); 57 | return seriesRenderData; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/realize/ListGenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.realize; 2 | 3 | import com.deepoove.poi.data.NumbericRenderData; 4 | import com.jiashn.generateReport.domain.LabelData; 5 | import com.jiashn.generateReport.domain.ListRenderData; 6 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 7 | import com.jiashn.generateReport.factory.GenerateWordFactory; 8 | import com.jiashn.generateReport.service.GenerateWord; 9 | import org.springframework.stereotype.Component; 10 | 11 | import javax.annotation.PostConstruct; 12 | 13 | /** 14 | * @author: jiangjs 15 | * @description: 16 | * @date: 2023/6/2 15:42 17 | **/ 18 | @Component 19 | public class ListGenerateWord implements GenerateWord { 20 | @PostConstruct 21 | private void init(){ 22 | GenerateWordFactory.register(WordContentTypeEnum.LIST,this); 23 | } 24 | @Override 25 | public Object generateWord(LabelData data) { 26 | ListRenderData listData = (ListRenderData) data; 27 | return new NumbericRenderData(listData.getPair(),listData.getList()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/realize/PictureGenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.realize; 2 | 3 | import com.deepoove.poi.data.PictureRenderData; 4 | import com.deepoove.poi.util.BytePictureUtils; 5 | import com.jiashn.generateReport.domain.LabelData; 6 | import com.jiashn.generateReport.domain.PictureContentData; 7 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 8 | import com.jiashn.generateReport.factory.GenerateWordFactory; 9 | import com.jiashn.generateReport.service.GenerateWord; 10 | import org.apache.commons.lang3.StringUtils; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.PostConstruct; 14 | 15 | /** 16 | * @author: jiangjs 17 | * @description: 18 | * @date: 2022/11/24 16:46 19 | **/ 20 | @Component 21 | public class PictureGenerateWord implements GenerateWord { 22 | 23 | @PostConstruct 24 | private void init(){ 25 | GenerateWordFactory.register(WordContentTypeEnum.PICTURE,this); 26 | } 27 | 28 | @Override 29 | public Object generateWord(LabelData data) { 30 | PictureContentData picture = (PictureContentData) data; 31 | return StringUtils.isNotBlank(picture.getPicUrl()) ? new PictureRenderData(picture.getWidth(),picture.getHeight(),picture.getPicType().getPicName(), 32 | BytePictureUtils.getUrlBufferedImage(picture.getPicUrl())) 33 | : new PictureRenderData(picture.getWidth(),picture.getHeight(),picture.getFile()); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/realize/TableGenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.realize; 2 | 3 | import com.deepoove.poi.data.MiniTableRenderData; 4 | import com.deepoove.poi.data.RowRenderData; 5 | import com.jiashn.generateReport.domain.LabelData; 6 | import com.jiashn.generateReport.domain.TableSeriesRenderData; 7 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 8 | import com.jiashn.generateReport.factory.GenerateWordFactory; 9 | import com.jiashn.generateReport.service.GenerateWord; 10 | import org.springframework.stereotype.Component; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | 16 | /** 17 | * @author: jiangjs 18 | * @description: 19 | * @date: 2022/11/24 17:20 20 | **/ 21 | @Component 22 | public class TableGenerateWord implements GenerateWord { 23 | @PostConstruct 24 | private void init(){ 25 | GenerateWordFactory.register(WordContentTypeEnum.TABLE,this); 26 | } 27 | @Override 28 | public Object generateWord(LabelData data) { 29 | TableSeriesRenderData tableData = (TableSeriesRenderData) data; 30 | RowRenderData header = RowRenderData.build(tableData.getHeader()); 31 | List contentData = new ArrayList<>(); 32 | tableData.getContents().forEach(con ->{ 33 | contentData.add(RowRenderData.build(con)); 34 | }); 35 | return new MiniTableRenderData(header,contentData); 36 | } 37 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/realize/TextGenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.realize; 2 | 3 | import com.jiashn.generateReport.domain.LabelData; 4 | import com.jiashn.generateReport.domain.TextContentData; 5 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 6 | import com.jiashn.generateReport.factory.GenerateWordFactory; 7 | import com.jiashn.generateReport.service.GenerateWord; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.PostConstruct; 11 | import java.util.Objects; 12 | 13 | /** 14 | * @author: jiangjs 15 | * @description: 文本内容实现 16 | * @date: 2022/11/24 14:28 17 | **/ 18 | @Component 19 | public class TextGenerateWord implements GenerateWord { 20 | 21 | @PostConstruct 22 | public void init(){ 23 | GenerateWordFactory.register(WordContentTypeEnum.TEXT,this); 24 | } 25 | 26 | @Override 27 | public Object generateWord(LabelData data) { 28 | TextContentData contentData = (TextContentData) data; 29 | return Objects.nonNull(contentData.getLinkData()) ? contentData.getLinkData() : 30 | Objects.nonNull(contentData.getRenderData()) ? contentData.getRenderData() : contentData.getContent(); 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/service/ApachePoitlService.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.service; 2 | 3 | /** 4 | * @author: jiangjs 5 | * @description: 6 | * @date: 2022/11/23 17:13 7 | **/ 8 | public interface ApachePoitlService { 9 | void generateCharts(); 10 | } 11 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/service/GenerateWord.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.service; 2 | 3 | import com.jiashn.generateReport.domain.LabelData; 4 | 5 | /** 6 | * @author: jiangjs 7 | * @description: 8 | * @date: 2022/11/24 13:55 9 | **/ 10 | public interface GenerateWord { 11 | 12 | Object generateWord(LabelData data); 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/service/impl/ApachePoitlServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.service.impl; 2 | import com.deepoove.poi.data.ChartSingleSeriesRenderData; 3 | import com.deepoove.poi.data.NumbericRenderData; 4 | import com.deepoove.poi.data.SeriesRenderData; 5 | import com.deepoove.poi.data.TextRenderData; 6 | import com.deepoove.poi.data.style.Style; 7 | import com.jiashn.generateReport.domain.*; 8 | import com.jiashn.generateReport.enums.CharCombinationType; 9 | import com.jiashn.generateReport.enums.PicTypeEnum; 10 | import com.jiashn.generateReport.enums.WordContentTypeEnum; 11 | import com.jiashn.generateReport.realize.TableGenerateWord; 12 | import com.jiashn.generateReport.service.ApachePoitlService; 13 | import com.jiashn.generateReport.util.OperateWordManage; 14 | import com.sun.org.apache.bcel.internal.generic.NEW; 15 | import javafx.application.Application; 16 | import org.apache.catalina.core.ApplicationContext; 17 | import org.apache.poi.ss.formula.functions.T; 18 | import org.springframework.beans.factory.annotation.Autowired; 19 | import org.springframework.core.io.ClassPathResource; 20 | import org.springframework.stereotype.Service; 21 | 22 | import java.io.File; 23 | import java.io.IOException; 24 | import java.util.ArrayList; 25 | import java.util.Arrays; 26 | import java.util.List; 27 | 28 | /** 29 | * @author: jiangjs 30 | * @description: 31 | * @date: 2022/11/23 17:13 32 | **/ 33 | @Service 34 | public class ApachePoitlServiceImpl implements ApachePoitlService { 35 | 36 | private static final String TEMPLATE_PATH = "static/template/demo_template.docx"; 37 | 38 | @Override 39 | public void generateCharts() { 40 | File templateFile = null; 41 | try { 42 | templateFile = new ClassPathResource(TEMPLATE_PATH).getFile(); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | List generates = new ArrayList<>(); 47 | //文本 48 | TextContentData contentData = new TextContentData(); 49 | contentData.setContent("2022年月通报函生成报告").setLabelName("title").setTypeEnum(WordContentTypeEnum.TEXT); 50 | generates.add(contentData); 51 | //带样式文本 52 | TextContentData typeData = new TextContentData(); 53 | typeData.setRenderData(new TextRenderData("cc0000","这是带样式的内容")).setLabelName("typeContent").setTypeEnum(WordContentTypeEnum.TEXT); 54 | generates.add(typeData); 55 | //插入图片 56 | PictureContentData picData = new PictureContentData(); 57 | picData.setWidth(200).setHeight(160).setPicType(PicTypeEnum.JPG).setFile(new File("D:\\down\\java.jpg")) 58 | .setLabelName("picture").setTypeEnum(WordContentTypeEnum.PICTURE); 59 | generates.add(picData); 60 | //插入表格 61 | TableSeriesRenderData tableData = new TableSeriesRenderData(); 62 | List contents = Arrays.asList(new TextRenderData[]{new TextRenderData("科教1班"), 63 | new TextRenderData("1")},new TextRenderData[]{new TextRenderData("幼儿3班"),new TextRenderData("6")}); 64 | tableData.setHeader(new TextRenderData[]{new TextRenderData("班级"),new TextRenderData("排名")}) 65 | .setContents(contents).setLabelName("showTable").setTypeEnum(WordContentTypeEnum.TABLE); 66 | generates.add(tableData); 67 | //插入列表 68 | ListRenderData listRenderData = new ListRenderData(); 69 | List listData = Arrays.asList(new TextRenderData("排序1"),new TextRenderData("排序2"),new TextRenderData("排序3")); 70 | listRenderData.setList(listData).setPair(NumbericRenderData.FMT_LOWER_ROMAN).setTypeEnum(WordContentTypeEnum.LIST).setLabelName("numList"); 71 | generates.add(listRenderData); 72 | //折线 73 | ChartSeriesRenderData lineData = new ChartSeriesRenderData(); 74 | List lineRenderData = new ArrayList<>(); 75 | ChartSeriesRenderData.RenderData numRenderData = new ChartSeriesRenderData.RenderData(); 76 | ChartSeriesRenderData.RenderData moneyRenderData = new ChartSeriesRenderData.RenderData(); 77 | numRenderData.setRenderTitle("项目数量").setData(new Double[] {-11.02,-19.42,-10.61,-11.41,-7.91,-5.44,-5.30,-2.75,-1.24,0.35}); 78 | moneyRenderData.setRenderTitle("投资额").setData(new Number[]{-12.66,-19.41,-15.16,-19.72,-17.05,-15.92,-15.10,-13.04,-10.65,-9.15}); 79 | lineRenderData.add(numRenderData); 80 | lineRenderData.add(moneyRenderData); 81 | lineData.setTitle("1-10月份全国新开工项目数量、投资额增速") 82 | .setCategories(new String[] {"1月","2月","3月","4月","5月","6月","7月","8月","9月","10月"}) 83 | .setSenderData(lineRenderData).setTypeEnum(WordContentTypeEnum.CHART).setLabelName("speedLine"); 84 | generates.add(lineData); 85 | //柱状图 86 | ChartSeriesRenderData barData = new ChartSeriesRenderData(); 87 | List barRenderData = new ArrayList<>(); 88 | ChartSeriesRenderData.RenderData openRenderData = new ChartSeriesRenderData.RenderData(); 89 | ChartSeriesRenderData.RenderData moneyData = new ChartSeriesRenderData.RenderData(); 90 | openRenderData.setRenderTitle("开工数量").setData(new Number[]{40,50,45,12,21,18,21,28,21,18,28,18,20,19,-10,-9,-10,19,39,31,20,19,-10,-9,-10,19,39,31,-10,19,39}); 91 | moneyData.setRenderTitle("投资额").setData(new Number[]{20,-22,-12,8,-10,-14,-10,-10,-8,-2,-8,-1,-9,-21,-9,-7,-21,-10,21,-29,-50,-21,-9,-7,-21,-10,21,-29,-21,-10,21}); 92 | barRenderData.add(openRenderData); 93 | barRenderData.add(moneyData); 94 | barData.setTitle("各省(自治区)直辖市新开项目数量、投资额同比情况") 95 | .setCategories(new String[] {"贵州","西藏","黑龙江","浙江","湖北","江苏","四川","福建","安徽","海南","山西","广西","青海","广东","甘肃", 96 | "云南","宁夏","新疆","湖南","北京","河北","山西","山东","内蒙古","天津","江西","吉林","河南","重庆","上海","辽宁"}) 97 | .setSenderData(barRenderData).setTypeEnum(WordContentTypeEnum.CHART).setLabelName("investmentRatio"); 98 | generates.add(barData); 99 | //生成饼图 100 | ChartSeriesRenderData areaData = new ChartSeriesRenderData(); 101 | List areaRenderDatas = new ArrayList<>(); 102 | ChartSeriesRenderData.RenderData areaRenderData = new ChartSeriesRenderData.RenderData(); 103 | areaRenderData.setData(new Number[]{17098242, 9984670, 9826675, 9596961}).setRenderTitle("投资额") 104 | .setComboType(SeriesRenderData.ComboType.AREA); 105 | areaRenderDatas.add(areaRenderData); 106 | areaData.setTitle("国家投资额").setSenderData(areaRenderDatas).setCharType(CharCombinationType.Single) 107 | .setCategories(new String[]{"俄罗斯", "加拿大", "美国", "中国"}) 108 | .setLabelName("areaShow").setTypeEnum(WordContentTypeEnum.CHART); 109 | generates.add(areaData); 110 | 111 | //横向柱状图 112 | ChartSeriesRenderData lateralData = new ChartSeriesRenderData(); 113 | List lateralRenderData = new ArrayList<>(); 114 | ChartSeriesRenderData.RenderData lateralYearData = new ChartSeriesRenderData.RenderData(); 115 | ChartSeriesRenderData.RenderData lateralMoneyData = new ChartSeriesRenderData.RenderData(); 116 | lateralYearData.setRenderTitle("2021年").setData(new Number[]{400,200}); 117 | lateralMoneyData.setRenderTitle("2022年").setData(new Number[]{456,255}); 118 | lateralRenderData.add(lateralYearData); 119 | lateralRenderData.add(lateralMoneyData); 120 | lateralData.setTitle("工程建设项目建设周期同比情况") 121 | .setCategories(new String[] {"从立项到开工的用时","从开工到验收的用时"}) 122 | .setSenderData(lateralRenderData).setTypeEnum(WordContentTypeEnum.CHART).setLabelName("cycleRadio"); 123 | generates.add(lateralData); 124 | //组合图表 125 | ChartSeriesRenderData groupData = new ChartSeriesRenderData(); 126 | List groupRenderData = new ArrayList<>(); 127 | ChartSeriesRenderData.RenderData unOpenData = new ChartSeriesRenderData.RenderData(); 128 | ChartSeriesRenderData.RenderData openRadioData = new ChartSeriesRenderData.RenderData(); 129 | unOpenData.setComboType(SeriesRenderData.ComboType.BAR).setRenderTitle("未开工项目数(个)") 130 | .setData(new Number[]{55, 35, 23, 76, 60, 65.1, 70.2, 75.3, 80.4, 85.5, 90.6, 95.7, 26, 131 | 76, 60, 65.1, 70.2, 75.3, 80.4, 95.7, 26, 76, 60, 65.1, 70.2, 75.3, 95.7, 26, 76, 60, 65.1}); 132 | openRadioData.setComboType(SeriesRenderData.ComboType.LINE).setRenderTitle("开工率(%)") 133 | .setData(new Number[]{34,45,23,67,34,45,23,67,34,45,23,67,23,67,34,45,23,45,23,67,23,67,34,45,23,45,67,23,67,34,45}); 134 | groupRenderData.add(unOpenData); 135 | groupRenderData.add(openRadioData); 136 | groupData.setTitle("各省(区、市)签约项目开工情况") 137 | .setCategories(new String[] {"北京","吉林","云南","上海","安徽","浙江","江西","四川","陕西","甘肃","江苏","广西","内蒙古","福建","天津","海南","黑龙江", 138 | "贵州","山东","河北","辽宁","湖北","宁夏","广东","重庆","河南","新疆","山西","湖南","青海","兵团"}) 139 | .setSenderData(groupRenderData).setTypeEnum(WordContentTypeEnum.CHART).setLabelName("openCondition"); 140 | generates.add(groupData); 141 | //生成word 142 | OperateWordManage.generateWordContent(templateFile,"D:\\down\\output.docx",generates); 143 | } 144 | } -------------------------------------------------------------------------------- /src/main/java/com/jiashn/generateReport/util/OperateWordManage.java: -------------------------------------------------------------------------------- 1 | package com.jiashn.generateReport.util; 2 | 3 | import com.deepoove.poi.XWPFTemplate; 4 | import com.jiashn.generateReport.domain.LabelData; 5 | import com.jiashn.generateReport.factory.GenerateWordFactory; 6 | import com.jiashn.generateReport.service.GenerateWord; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.io.File; 11 | import java.io.FileOutputStream; 12 | import java.util.*; 13 | 14 | /** 15 | * @author: jiangjs 16 | * @description: 操作word内容 17 | * @date: 2022/11/24 11:32 18 | **/ 19 | public class OperateWordManage { 20 | private final static Logger log = LoggerFactory.getLogger(OperateWordManage.class); 21 | 22 | public static void generateWordContent(File tempFileFile, String destFilePath, List contents){ 23 | FileOutputStream fos = null; 24 | XWPFTemplate template = null; 25 | try { 26 | template = XWPFTemplate.compile(tempFileFile).render(new HashMap(contents.size()){{ 27 | contents.forEach(content ->{ 28 | GenerateWord backData = GenerateWordFactory.getBackData(content.getTypeEnum()); 29 | put(content.getLabelName(),backData.generateWord(content)); 30 | }); 31 | }}); 32 | fos = new FileOutputStream(destFilePath); 33 | template.write(fos); 34 | fos.flush(); 35 | }catch (Exception e){ 36 | log.error("替换生成图表报错:{}",e.getMessage()); 37 | e.printStackTrace(); 38 | }finally { 39 | try{ 40 | if (Objects.nonNull(fos)){ 41 | fos.close(); 42 | } 43 | if (Objects.nonNull(template)){ 44 | template.close(); 45 | } 46 | }catch (Exception e){ 47 | log.error("关闭数据流报错:{}",e.getMessage()); 48 | e.printStackTrace(); 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #端口 2 | server: 3 | port: 8090 4 | servlet: 5 | context-path: /report 6 | -------------------------------------------------------------------------------- /src/main/resources/static/template/demo_template.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lovejiashn/generate_report/c43a73ac5cf94ba68c2a2daad28c81c3992934a4/src/main/resources/static/template/demo_template.docx --------------------------------------------------------------------------------