网站上传连接失败的原因,做淘宝美工和网站设计那个好,微信制作软件,网站开发工具哪个好一、概述#xff1a; 1. springboot如何生成pdf#xff0c;接口可以预览可以下载 2. vue下载通过bold如何下载 3. 一些细节#xff1a;页脚、页眉、水印、每一页得样式添加
二、直接上代码【主要是一个记录下次开发更快】
模板位置 1. 导入pom包
dependencyg…一、概述 1. springboot如何生成pdf接口可以预览可以下载 2. vue下载通过bold如何下载 3. 一些细节页脚、页眉、水印、每一页得样式添加
二、直接上代码【主要是一个记录下次开发更快】
模板位置 1. 导入pom包
dependencygroupIdcom.itextpdf/groupIdartifactIdhtml2pdf/artifactIdversion5.0.5/version
/dependency
!-- 中文字体支持 --
dependencygroupIdcom.itextpdf/groupIdartifactIdfont-asian/artifactIdversion7.2.1/version
/dependency
2. 写工具类
[1] 页眉工具类
import com.itextpdf.io.image.ImageDataFactory;
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.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import org.springframework.util.StringUtils;
import java.net.MalformedURLException;
import java.net.URL;public class HeaderMarkerEventHandler implements IEventHandler {/*** pdf字体*/private final PdfFont pdfFont;/*** 页眉显示*/private final String title;/*** logo地址*/private String logoUrl;public HeaderMarkerEventHandler(PdfFont pdfFont, String title) {this.pdfFont pdfFont;this.title title;}public HeaderMarkerEventHandler(PdfFont pdfFont, String title, String logoUrl) {this.pdfFont pdfFont;this.title title;this.logoUrl logoUrl;}Overridepublic void handleEvent(Event event) {PdfDocumentEvent docEvent (PdfDocumentEvent) event;PdfDocument pdf docEvent.getDocument();PdfPage page docEvent.getPage();Rectangle pageSize page.getPageSize();PdfCanvas pdfCanvas new PdfCanvas(page.getLastContentStream(), page.getResources(), pdf);Canvas canvas new Canvas(pdfCanvas, pageSize);float x pageSize.getRight() - 60;float y pageSize.getTop() - 32;Paragraph p new Paragraph(title).setFontSize(9).setFont(pdfFont);// 页眉字体显示得位置canvas.showTextAligned(p, x, y, TextAlignment.RIGHT);// 加载图片if (!StringUtils.isEmpty(logoUrl)) {try {URL url new URL(logoUrl);Image logo new Image(ImageDataFactory.create(url));logo.scaleAbsolute(100, 20);logo.setMarginLeft(30);logo.setMarginTop(15);canvas.add(logo);} catch (MalformedURLException e) {System.out.println(logo 无法解析: logoUrl);}}canvas.close();}
}
[2] 水印工具类 import com.itextpdf.kernel.colors.WebColors;
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.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import java.io.IOException;/*** 生成 pdf 水印*/
public class WaterMarkEventHandler implements IEventHandler {/*** 水印内容*/private final String waterMarkContent;/*** 一页中有几列水印*/private final int waterMarkX;/*** 一页中每列有多少水印*/private final int waterMarkY;public WaterMarkEventHandler(String waterMarkContent) {this(waterMarkContent, 5, 5);}public WaterMarkEventHandler(String waterMarkContent, int waterMarkX, int waterMarkY) {this.waterMarkContent waterMarkContent;this.waterMarkX waterMarkX;this.waterMarkY waterMarkY;}Overridepublic void handleEvent(Event event) {PdfDocumentEvent documentEvent (PdfDocumentEvent) event;PdfDocument document documentEvent.getDocument();PdfPage page documentEvent.getPage();Rectangle pageSize page.getPageSize();PdfFont pdfFont null;try {pdfFont PdfFontFactory.createFont(STSongStd-Light, UniGB-UCS2-H);} catch (IOException e) {throw new RuntimeException(e);}PdfCanvas pdfCanvas new PdfCanvas(page.newContentStreamAfter(), page.getResources(), document);Paragraph waterMark new Paragraph(waterMarkContent).setOpacity(0.5f);Canvas canvas new Canvas(pdfCanvas, pageSize).setFontColor(WebColors.getRGBColor(lightgray)).setFontSize(16).setFont(pdfFont);for (int i 0; i waterMarkX; i) {for (int j 0; j waterMarkY; j) {canvas.showTextAligned(waterMark, (150 i * 300), (160 j * 150), document.getNumberOfPages(),TextAlignment.CENTER, VerticalAlignment.BOTTOM, 120);}}canvas.close();}
}
[3]添加页脚工具类 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.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;/*** 生成 pdf 页码*/
public class PageEventHandler implements IEventHandler {/*** pdf字体*/private final PdfFont pdfFont;public PageEventHandler(PdfFont pdfFont) {this.pdfFont pdfFont;}Overridepublic void handleEvent(Event event) {PdfDocumentEvent documentEvent (PdfDocumentEvent) event;PdfDocument document documentEvent.getDocument();PdfPage page documentEvent.getPage();Rectangle pageSize page.getPageSize();PdfCanvas pdfCanvas new PdfCanvas(page.getLastContentStream(), page.getResources(), document);Canvas canvas new Canvas(pdfCanvas, pageSize);float x (pageSize.getLeft() pageSize.getRight()) / 2;float y pageSize.getBottom() 15;Paragraph paragraph new Paragraph(document.getPageNumber(page) ).setFontSize(10).setFont(pdfFont);canvas.showTextAligned(paragraph, x, y, TextAlignment.CENTER);canvas.close();}
}
[4]工具类重点说一下这个字体 1. 本文第一个图里面font得字体路径在Windows电脑C:\Windows\Fonts看中哪个字体就直接拷贝进去进会自动生成ttc文件我拷贝得是宋体和微软雅黑主要解决加粗 2.前端
font-family: MicrosoftYaHei-Bold;
这个字体得名字日下图 import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
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.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.layout.font.FontProvider;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.context.Context;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import java.io.*;
import java.nio.charset.StandardCharsets;/*** PDF工具** author ppp* date 2022/8/5*/
public class Html2PdfUtil {static {Velocity.setProperty(RuntimeConstants.INPUT_ENCODING, StandardCharsets.UTF_8);Velocity.setProperty(RuntimeConstants.RESOURCE_LOADER, classpath);Velocity.setProperty(classpath.resource.loader.class, ClasspathResourceLoader.class.getName());Velocity.init();}/*** 据模板生成pfd格式文件** param context 上下文对象* param template pdf模板* param outputStream 生成ofd文件输出流*/public static void pdfFile(Context context, String template, OutputStream outputStream, String watermarkText) throws IOException {PdfWriter pdfWriter null;PdfDocument pdfDocument null;StringWriter writer null;try {pdfWriter new PdfWriter(outputStream);pdfDocument new PdfDocument(pdfWriter);PageSize pageSize new PageSize(842.0F,595.0F);pdfDocument.setDefaultPageSize(pageSize);ConverterProperties properties new ConverterProperties();// 添加字体FontProvider fontProvider new FontProvider();// 字体设置解决中文不显示问题PdfFont sysFont PdfFontFactory.createFont(STSongStd-Light, UniGB-UCS2-H);fontProvider.addFont(sysFont.getFontProgram(), UniGB-UCS2-H);
// 添加宋体html中使用SimSun不指定则默认为第一个引入的字体sysFont PdfFontFactory.createFont(font/simsun.ttc,0, PdfEncodings.IDENTITY_H);fontProvider.addFont(sysFont.getFontProgram(), PdfEncodings.IDENTITY_H);// 添加微软雅黑html中使用MicrosoftYaHeisysFont PdfFontFactory.createFont(font/msyh.ttc,0, PdfEncodings.IDENTITY_H);fontProvider.addFont(sysFont.getFontProgram(), PdfEncodings.IDENTITY_H);// 添加微软雅黑粗体html中使用MicrosoftYaHei-BoldsysFont PdfFontFactory.createFont(font/msyhbd.ttc,0, PdfEncodings.IDENTITY_H);fontProvider.addFont(sysFont.getFontProgram(), PdfEncodings.IDENTITY_H);// 处理微软雅黑及粗体描述符错乱问题processYaHeiFontDescriptor(fontProvider);properties.setFontProvider(fontProvider);// 添加页眉
// pdfDocument.addEventHandler(PdfDocumentEvent.START_PAGE, new HeaderMarkerEventHandler(sysFont, 学校));// 添加水印pdfDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE, new WaterMarkEventHandler(watermarkText));// 添加页脚pdfDocument.addEventHandler(PdfDocumentEvent.END_PAGE, new PageEventHandler(sysFont));// 读取html模板和赋值Template pfdTemplate Velocity.getTemplate(template, UTF-8);writer new StringWriter();pfdTemplate.merge(context, writer);// 构建带有样式的 HTML 字符串StringBuilder htmlWithStyles new StringBuilder();htmlWithStyles.append(htmlheadstyle);// 如果有边距参数则添加到样式中htmlWithStyles.append(page { );htmlWithStyles.append(margin-bottom: ).append(30).append(mm; );htmlWithStyles.append(});htmlWithStyles.append(/style/headbody).append(/body/html);// html转换PDFHtmlConverter.convertToPdf(writer.toString(), pdfDocument, properties);} catch (Exception e) {throw new RuntimeException(PFD文件生成失败, e);}finally {pdfDocument.close();writer.close();pdfWriter.close();}}
}
3.html模板里面那个分页就是新开一页估计有点问题 【1】、td 换行得自己加
!DOCTYPE html
html
headmeta charsetUTF-8/
/head
body
div classcontianerdivdiv classfourth_titleh42-2 专业群建设总目标/h4/divdiv classthird_conp classpFontCon$!{xxxxmb.zyqjszmb}/p/div/divdiv#foreach($html in $canVasHtml)div classpage-break$html/div#end/div/div
/body
styleh1,h2 {font-style: italic;font-family: MicrosoftYaHei-Bold;text-align: center;font-weight: bold; /* 加粗文本 */}td{white-space:normal;word-wrap:break-word;word-break:break-all;}media print {.page-break {page-break-before: always; /* 在元素之前插入分页 */}}
/* 每次新开一个分页 */.page-break {page-break-before: always; /* 在元素之前插入分页 */}
/style
/html
4. Service 只留了一部分代码
Override
public void downloadAchievementsByPdf( HttpServletResponse response, HttpServletRequest request) throws IOException {OutputStream outputStream null;try {response.reset();String fileName schooleInfo.getXxmc();
// 这个是直接下载response.setHeader(Content-Type, application/pdf);response.setHeader(Content-Disposition, attachment;filename URLEncoder.encode(fileName .pdf, utf-8));// 这个是预览,访问接口页面打开得是一个FPD预览得页面
// response.setContentType(application/pdf);
// response.addHeader(Content-Disposition, inline; filename fileName);VelocityContext context new VelocityContext();setBaseInfo(context, schooleInfo);context.put(zyqxxList, zyqjbxxTS);context.put(xxxxmb, zyqjbxxTInfoOne);// 获取指标数据ListMapString, Object maps (ListMapString, Object) treeWithCanvas(schoolBookId, isTask, taskId, schoolId).get(data);ListString canVasHtml PdfTemplate.getCanVasHtml(maps);context.put(canVasHtml, canVasHtml);outputStream response.getOutputStream();Html2PdfUtil.pdfFile(context, templates/jxzpbPdf.html, outputStream, schooleInfo.getXxmc());} catch (Exception e) {e.printStackTrace();}finally {outputStream.close();}
}private void setBaseInfo(VelocityContext context, XxbcxxT schooleInfo) {// 1. 查询学校基本信息context.put(xmdw, schooleInfo.getXxmc());context.put(xmmc, schooleInfo.getXmmc());context.put(tbrq, DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD));context.put(jbdw, schooleInfo.getJbdw());context.put(szsf, schooleInfo.getSfbm() null ? : ProvinceJson.getProName(schooleInfo.getSfbm()));
}
5. VUE代码 return request(url, {...params,method: GET,responseType: blob}).then((data) {const aLink document.createElement(a);const blob new Blob([data],{type: application/pdf}); aLink.style.display none;aLink.href URL.createObjectURL(blob);aLink.setAttribute(download, fileName); document.body.appendChild(aLink);aLink.click();URL.revokeObjectURL(aLink.href); // 清除引用document.body.removeChild(aLink);});
三、最后还有一个加粗得问题。思路就是需要引入字体文件