Skip to content

Traffic conversion funnel (government service portal) — generate this PDF with Java (Funnel)

JQuick-PdfBiz Demo

Funnel2 页 A4 · 85 KB

Measures the conversion rate from visit to completion for online transactions and quantifies the effect of the digital service rollout.

Download the PDFView raw template fileBack to all demos

Traffic conversion funnel (government service portal) — Funnel
Rendered output

Output specs

PDF pages
2
Chart type
Funnel
Template lines
101
Source lines
104

Java source · JQuickBiz40TrafficFunnelTest.java

This is the complete test class that produced the PDF above — copy it and run as-is; see the quick-start section for the Maven dependency.

/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright (c) [2025-2099] Martin ([email protected])
 */
package com.github.paohaijiao.demo.biz;

import com.github.paohaijiao.JOption;
import com.github.paohaijiao.config.JPdfConfig;
import com.github.paohaijiao.demo.constant.JQuickConstant;
import com.github.paohaijiao.enums.JChartType;
import com.github.paohaijiao.executor.JQuickPdfFactory;
import com.github.paohaijiao.factory.JChartRendererFactory;
import com.github.paohaijiao.funnel.*;
import org.junit.Test;

import java.awt.Color;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

/**
 * 业务场景 Demo 40:流量转化漏斗(政务服务平台 / 线上办件)
 *
 * <p>业务场景:政务服务平台统计线上办件的全流程转化,从访问到实名认证、表单填写、
 * 材料上传直至提交成功,用于识别流程堵点、优化办事体验,主色采用沉稳青绿 #006064。</p>
 * <p>实际图表类型:{@link JChartType#Funnel} 漏斗图(展示办件流程各环节的逐级递减)。</p>
 *
 * <p>模板:{@code report/biz/40_traffic_funnel.txt};图表以 SVG 文本形式绑定到模板的
 * {@code ${svg}} 占位符,输出到 {@code D:\test\biz\40_traffic_funnel.pdf}。</p>
 *
 * <p>图表尺寸说明:图表按 700pt × 400pt(宽 × 高)的横版比例设计;模板中 {@code <svg>}
 * 只声明宽度、不声明高度,因此宽度被页面自动收窄时高度会按原比例同步缩放,不会纵向拉伸变形。</p>
 *
 * @author Martin
 * @version 1.0.0
 */
public class JQuickBiz40TrafficFunnelTest {

    public static final String path = JQuickConstant.path;

    @Test
    public void biz40TrafficFunnel() throws IOException {
        JFunnelOption funnelOption = JFunnelOption.createDefaultFunnel();
        funnelOption = funnelOption
                .title(new Title().text("线上办件流程转化漏斗").subtext("2024年政务服务平台办件全流程(单位:次)"))
                .funnel(new Funnel()
                        .width(600)
                        .topY(80)
                        .bottomY(200)
                        .gap(2)
                        .borderColor(Color.GRAY)
                ).series(Collections.singletonList(
                        new Series()
                                .name("办件环节")
                                .type("funnel")
                                .data(Arrays.asList(
                                        new DataItem("访问页面", 128000),
                                        new DataItem("实名认证", 76200),
                                        new DataItem("表单填写", 51800),
                                        new DataItem("材料上传", 39600),
                                        new DataItem("提交成功", 31400)
                                ))))
                // 与主色 #006064 同色系的低饱和青绿渐变,依次变浅
                .colors(
                        new Color(0, 96, 100),
                        new Color(0, 121, 122),
                        new Color(38, 145, 143),
                        new Color(84, 168, 165),
                        new Color(128, 190, 186)
                );
        JOption option = new JOption();
        option.setFunnelOption(funnelOption);

        String svg = JChartRendererFactory.renderChart(JChartType.Funnel, option);

        File dir = new File(path + "biz");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        FileOutputStream fileOutputStream = new FileOutputStream(path + "biz/40_traffic_funnel.pdf");
        JPdfConfig config = new JPdfConfig();
        // 开启 flex 行布局,使模板中的 display:flex 生效(图表居中)
        config.getLayoutConfig().setFlexLayout(true);
        JQuickPdfFactory factory = new JQuickPdfFactory(config);
        factory.bind("svg", svg);
        byte[] bytes = factory.executeResource("report/biz/40_traffic_funnel.txt");
        fileOutputStream.write(bytes);
        fileOutputStream.close();
    }
}

Minimal invocation (3 lines)

Skip the full test class — the core is these three lines: bind the chart SVG, execute the template, get the PDF bytes. Copy them straight into your project.

// config 可省略;svg 来自 JChartRendererFactory.renderChart(...),见下方完整源码
factory.bind("svg", svg);
byte[] pdf = new JQuickPdfFactory(config).executeResource("report/biz/40_traffic_funnel.txt");

Template file · 40_traffic_funnel.txt

An HTML-like template with inline CSS that renders to PDF once bound to data. The full template is below — copy it or download the raw file.

<pdf>
<body>
  <div style="textAlignment:center; marginBottom:10px; padding:14px; background:#006064; borderRadius:4px">
    <h1 style="textAlignment:center; color:white; marginBottom:6px; fontSize:18; bold:true">'线上办件流程转化漏斗分析'</h1>
    <p style="color:white; fontSize:10; margin:2px">'统计周期:2024年1月1日 - 2024年12月31日'</p>
    <p style="color:white; fontSize:10; margin:2px">'编制单位:市政务服务中心 | 报送对象:政务服务优化专班'</p>
  </div>

  <div style="display:flex; justifyContent:space-between; marginBottom:12px; keepTogether:true">
    <div style="width:132px; minHeight:54px; background:#E5F1F2; borderRadius:4px; padding:8px; verticalAlignment:middle">
      <p style="color:#006064; fontSize:16; bold:true; textAlignment:center; marginBottom:2px">'128,000'</p>
      <p style="color:#5A6B7C; fontSize:9; textAlignment:center">'页面访问量(次)'</p>
    </div>
    <div style="width:132px; minHeight:54px; background:#E5F1F2; borderRadius:4px; padding:8px; verticalAlignment:middle">
      <p style="color:#006064; fontSize:16; bold:true; textAlignment:center; marginBottom:2px">'31,400'</p>
      <p style="color:#5A6B7C; fontSize:9; textAlignment:center">'提交成功(次)'</p>
    </div>
    <div style="width:132px; minHeight:54px; background:#E5F1F2; borderRadius:4px; padding:8px; verticalAlignment:middle">
      <p style="color:#006064; fontSize:16; bold:true; textAlignment:center; marginBottom:2px">'24.5%'</p>
      <p style="color:#5A6B7C; fontSize:9; textAlignment:center">'全流程转化率'</p>
    </div>
    <div style="width:132px; minHeight:54px; background:#E5F1F2; borderRadius:4px; padding:8px; verticalAlignment:middle">
      <p style="color:#BF360C; fontSize:16; bold:true; textAlignment:center; marginBottom:2px">'51,800'</p>
      <p style="color:#5A6B7C; fontSize:9; textAlignment:center">'最大流失量(次)'</p>
    </div>
  </div>

  <div style="borderLeft:4px solid #006064; paddingLeft:8px; marginBottom:6px">
    <h2 style="color:#006064; fontSize:13; bold:true; marginTop:0; marginBottom:0">'一、办件流程转化漏斗'</h2>
  </div>
  <div style="marginBottom:12px">
    <div style="display:flex; justifyContent:center">
      <svg style="width:700pt">${svg}</svg>
    </div>
    <p style="fontSize:9; color:#6c757d; italic:true; marginTop:4px">'图 1  访问、认证、填写、上传、提交五个环节的逐级递减(数据来源:政务服务平台埋点统计)'</p>
  </div>

  <div style="borderLeft:4px solid #006064; paddingLeft:8px; marginBottom:6px">
    <h2 style="color:#006064; fontSize:13; bold:true; marginTop:0; marginBottom:0">'二、关键转化指标'</h2>
  </div>
  <div style="marginBottom:12px">
    <table style="width:540px; fontSize:10">
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'页面访问量(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'128,000'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'提交成功(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'31,400'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'实名认证(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'76,200'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'表单填写(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'51,800'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'材料上传(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'39,600'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'全流程转化率'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'24.5%'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'访问→实名转化'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'59.5%'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'实名→表单转化'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'68.0%'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'表单→材料转化'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'76.4%'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'材料→提交转化'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'79.3%'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'最大流失环节'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'访问→实名'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'流失量(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'51,800'</td>
      </tr>
      <tr>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'最小流失环节'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'材料→提交'</td>
        <td style="width:150px; backgroundColor:#E5F1F2; padding:5px; border:1px solid #DCE3EC">'流失量(次)'</td>
        <td style="width:120px; textAlign:right; padding:5px; border:1px solid #DCE3EC">'8,200'</td>
      </tr>
    </table>
  </div>

  <div style="borderLeft:4px solid #006064; paddingLeft:8px; marginBottom:6px">
    <h2 style="color:#006064; fontSize:13; bold:true; marginTop:0; marginBottom:0">'三、堵点分析与优化建议'</h2>
  </div>
  <list style="listStyleType:disc; paddingLeft:16px; fontSize:10">
    <li style="marginBottom:6px">'按环节递减:访问 128,000 次、实名认证 76,200 次、表单填写 51,800 次、材料上传 39,600 次、提交成功 31,400 次,全流程转化率 24.5%。'</li>
    <li style="marginBottom:6px">'第一堵点在认证环节:访问至实名认证仅转化 59.5%,流失 51,800 次,占全部流失量 96,600 次的 53.6%,是优化优先级最高的环节。'</li>
    <li style="marginBottom:6px">'后端环节较为顺畅:实名至表单、表单至材料、材料至提交的转化率分别为 68.0%、76.4%、79.3%,逐级提升,尾部流失仅 8,200 次。'</li>
    <li style="marginBottom:6px">'建议:简化实名认证路径、支持一次授权多次复用,并对表单填写过程增加暂存与引导,力争全流程转化率提升至 30% 以上。'</li>
  </list>

  <p style="textAlignment:right; color:#8a939b; fontSize:8">'注:环节转化率按上一环节为基数计算,全流程转化率为提交成功与页面访问量之比(31,400 / 128,000 = 24.5%)。'</p>
</body>
</pdf>

More demos in this group

The PDF, preview image, template and source code on this page were all produced by a real JQuick-Pdf run and are free to copy into your own project.