优化了PDF导出的效果
parent
cca08d73e9
commit
fd7fd56eb5
23
pom.xml
23
pom.xml
|
|
@ -49,18 +49,37 @@
|
|||
|
||||
<dependencies>
|
||||
|
||||
|
||||
<!-- iTextPDF核心库 - 用于PDF生成 -->
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>kernel</artifactId>
|
||||
<version>7.2.5</version>
|
||||
<version>7.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>io</artifactId>
|
||||
<version>7.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>forms</artifactId>
|
||||
<version>7.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>layout</artifactId>
|
||||
<version>7.2.5</version>
|
||||
<version>7.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.itextpdf</groupId>
|
||||
<artifactId>svg</artifactId>
|
||||
<version>7.2.4</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
|
|
|||
|
|
@ -4,35 +4,40 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.itextpdf.io.font.PdfEncodings;
|
||||
import com.itextpdf.kernel.colors.ColorConstants;
|
||||
import com.itextpdf.kernel.events.Event;
|
||||
import com.itextpdf.kernel.events.IEventHandler;
|
||||
import com.itextpdf.kernel.events.PdfDocumentEvent;
|
||||
import com.itextpdf.kernel.font.PdfFont;
|
||||
import com.itextpdf.kernel.font.PdfFontFactory;
|
||||
import com.itextpdf.kernel.geom.PageSize;
|
||||
import com.itextpdf.kernel.geom.Rectangle;
|
||||
import com.itextpdf.kernel.pdf.PdfDocument;
|
||||
import com.itextpdf.kernel.pdf.PdfPage;
|
||||
import com.itextpdf.kernel.pdf.PdfReader;
|
||||
import com.itextpdf.kernel.pdf.PdfWriter;
|
||||
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
|
||||
import com.itextpdf.layout.Document;
|
||||
import com.itextpdf.layout.borders.Border;
|
||||
import com.itextpdf.layout.element.Cell;
|
||||
import com.itextpdf.layout.element.Div;
|
||||
import com.itextpdf.layout.element.Paragraph;
|
||||
import com.itextpdf.layout.element.Table;
|
||||
import com.itextpdf.layout.properties.TextAlignment;
|
||||
import com.itextpdf.layout.properties.UnitValue;
|
||||
import com.whdc.mapper.*;
|
||||
import com.whdc.model.dto.AutoCallDto;
|
||||
import com.whdc.model.dto.FindPageDto;
|
||||
import com.whdc.model.entity.AutoCall;
|
||||
import com.whdc.model.entity.AutoCallPerson;
|
||||
import com.whdc.model.entity.AutoCallTask;
|
||||
import com.whdc.model.entity.WarnCallMap;
|
||||
import com.whdc.utils.DateUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.checkerframework.checker.units.qual.A;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.ParseException;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
|
@ -236,6 +241,45 @@ public class AutoCallApiService {
|
|||
return pageResult;
|
||||
}
|
||||
|
||||
private static class PageNumberEventHandler implements IEventHandler {
|
||||
protected PdfDocument pdfDoc;
|
||||
protected PdfFont font;
|
||||
protected int totalPages;
|
||||
|
||||
public PageNumberEventHandler(PdfDocument pdfDoc, PdfFont font, int totalPages) {
|
||||
this.pdfDoc = pdfDoc;
|
||||
this.font = font;
|
||||
this.totalPages = totalPages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(Event event) {
|
||||
PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
|
||||
PdfPage page = docEvent.getPage();
|
||||
int pageNumber = pdfDoc.getPageNumber(page);
|
||||
|
||||
Rectangle pageSize = page.getPageSize();
|
||||
PdfCanvas pdfCanvas = new PdfCanvas(page);
|
||||
try {
|
||||
pdfCanvas.setFontAndSize(font, 10);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Error setting font for page number", e);
|
||||
}
|
||||
|
||||
String text = String.format("第 %d 页/共 %d 页", pageNumber, totalPages);
|
||||
float textWidth = font.getWidth(text, 10);
|
||||
|
||||
float x = (pageSize.getLeft() + pageSize.getRight()) / 2 - textWidth / 2;
|
||||
float y = pageSize.getBottom() + 15;
|
||||
|
||||
pdfCanvas.beginText()
|
||||
.setTextMatrix(x, y)
|
||||
.showText(text)
|
||||
.endText()
|
||||
.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* pdf导出
|
||||
* @param records
|
||||
|
|
@ -246,15 +290,57 @@ public class AutoCallApiService {
|
|||
*/
|
||||
public ByteArrayInputStream exportPDF(List<AutoCallTask> records, HttpServletResponse response, String stm, String etm) {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
// 第一遍:计算总页数
|
||||
ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
|
||||
try (PdfWriter tempWriter = new PdfWriter(tempOut);
|
||||
PdfDocument tempPdfDoc = new PdfDocument(tempWriter);
|
||||
Document tempDoc = new Document(tempPdfDoc, PageSize.A4.rotate())) {
|
||||
|
||||
String fontPath = "/fonts/ChineseFonts.ttf";
|
||||
PdfFont font = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);
|
||||
tempDoc.setFont(font);
|
||||
|
||||
// 添加内容但不处理页码
|
||||
addPDFContent(tempDoc, records, stm, etm, font);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
// 获取总页数
|
||||
int totalPages;
|
||||
try (ByteArrayInputStream tempIn = new ByteArrayInputStream(tempOut.toByteArray());
|
||||
PdfReader tempReader = new PdfReader(tempIn);
|
||||
PdfDocument tempPdfDoc = new PdfDocument(tempReader)) {
|
||||
totalPages = tempPdfDoc.getNumberOfPages();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("Failed to calculate total pages", e);
|
||||
}
|
||||
|
||||
// 第二遍:正式生成PDF
|
||||
try (PdfWriter writer = new PdfWriter(out);
|
||||
// 设置A4横向(宽297mm,高210mm)
|
||||
PdfDocument pdfDoc = new PdfDocument(writer);
|
||||
Document document = new Document(pdfDoc, PageSize.A4.rotate())) {
|
||||
|
||||
// 添加标题
|
||||
String fontPath = "/fonts/ChineseFonts.ttf";//设置中文字体(没有这个,中文会乱码)
|
||||
String fontPath = "/fonts/ChineseFonts.ttf";
|
||||
PdfFont font = PdfFontFactory.createFont(fontPath, PdfEncodings.IDENTITY_H);
|
||||
document.setFont(font);
|
||||
|
||||
// 创建并注册页码事件处理器,传入总页数
|
||||
PageNumberEventHandler pageNumberEventHandler = new PageNumberEventHandler(pdfDoc, font, totalPages);
|
||||
pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, pageNumberEventHandler);
|
||||
|
||||
// 添加内容
|
||||
addPDFContent(document, records, stm, etm,font);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new ByteArrayInputStream(out.toByteArray());
|
||||
}
|
||||
private void addPDFContent(Document document, List<AutoCallTask> records, String stm, String etm, PdfFont font) throws IOException{
|
||||
document.add(new Paragraph("智能呼叫记录报表")
|
||||
.setFontSize(16)
|
||||
.setBold()
|
||||
|
|
@ -284,11 +370,11 @@ public class AutoCallApiService {
|
|||
150, // 预警名称
|
||||
120, // 智能呼叫时间
|
||||
100, // 县(市、区)
|
||||
160, // 呼叫对象及职务
|
||||
130, // 状态
|
||||
59, // 通话时长(秒)
|
||||
150, // 拨打时间
|
||||
150, // 结束时间
|
||||
100 // 呼叫对象及职务
|
||||
80, // 通话时长(秒)
|
||||
130, // 拨打时间
|
||||
130 // 结束时间
|
||||
};
|
||||
Table table = new Table(columnWidths);
|
||||
table.setKeepTogether(true);
|
||||
|
|
@ -296,15 +382,11 @@ public class AutoCallApiService {
|
|||
// 添加表头
|
||||
addTableHeader(table);
|
||||
// 添加数据行
|
||||
addTableData(table, records);
|
||||
addTableData(table, records,columnWidths,font);
|
||||
|
||||
document.add(table);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return new ByteArrayInputStream(out.toByteArray());
|
||||
}
|
||||
|
||||
// 更新表头(添加新字段)
|
||||
private void addTableHeader(Table table) {
|
||||
String[] headers = {
|
||||
|
|
@ -312,11 +394,11 @@ private void addTableHeader(Table table) {
|
|||
"预警名称",
|
||||
"智能呼叫时间",
|
||||
"县(市、区)",
|
||||
"呼叫对象及职务",
|
||||
"状态",
|
||||
"通话时长",
|
||||
"拨打时间",
|
||||
"结束时间",
|
||||
"呼叫对象及职务"
|
||||
"结束时间"
|
||||
};
|
||||
for (String header : headers) {
|
||||
table.addHeaderCell(new Cell()
|
||||
|
|
@ -327,12 +409,11 @@ private void addTableHeader(Table table) {
|
|||
}
|
||||
|
||||
// 更新数据行(适配新字段)
|
||||
private void addTableData(Table table, List<AutoCallTask> records) {
|
||||
private void addTableData(Table table, List<AutoCallTask> records, float[] columnWidths, PdfFont font) {
|
||||
int serialNumber = 1;
|
||||
for (AutoCallTask record : records) {
|
||||
// 拼接县(市、区)
|
||||
String region = record.getWarnCtnm() + record.getWarnCnnm();
|
||||
|
||||
// 处理呼叫对象信息
|
||||
StringBuilder callInfo = new StringBuilder();
|
||||
for (AutoCallPerson item : record.getCallList()) {
|
||||
|
|
@ -372,11 +453,11 @@ private void addTableHeader(Table table) {
|
|||
table.addCell(new Cell().add(new Paragraph(record.getWarnName() != null ? record.getWarnName() : "").setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(formattedCreateTime).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(region).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(callInfo.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(status.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(callTime.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(startTime.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(endTime.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
table.addCell(new Cell().add(new Paragraph(callInfo.toString()).setFontSize(10)).setKeepTogether(true));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue