当前位置: 首页 > news >正文

java分别使用 iText 7 库和iText 5 库 将excel转成PDF导出,以及如何对excel转PDF合并单元格

第一种

package com.junfun.pms.report.util;import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.property.TextAlignment;
import com.itextpdf.layout.property.UnitValue;
import com.itextpdf.text.*;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.*;
import org.apache.commons.io.IOUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;import javax.servlet.ServletOutputStream;
import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.List;/*** @description: 	PDF文件添加水印工具类* @author: liux* @date: 2024/5/23* @param: null* @return:*/public class PDFWatermarkExample {private static final String FONT_SIMFANG_PATH = "/font/simfang.ttf";private static final String ENCODING = "Identity-H";public static void addWatermark(String inputFile, String outputFile, String watermarkText) {try {PdfReader reader = new PdfReader(inputFile);PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));int numberOfPages = reader.getNumberOfPages();for (int i = 1; i <= numberOfPages; i++) {PdfContentByte content = stamper.getUnderContent(i);PdfGState gs = new PdfGState();gs.setFillOpacity(0.5f); // 设置水印透明度content.setGState(gs);ColumnText.showTextAligned(content,Element.ALIGN_CENTER,new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),reader.getPageSizeWithRotation(i).getWidth() / 2,reader.getPageSizeWithRotation(i).getHeight() / 2,45);}stamper.close();reader.close();} catch (Exception e) {e.printStackTrace();}}public static void addWatermarkMulti(String inputFile, String outputFile, String watermarkText) {try {PdfReader reader = new PdfReader(inputFile);PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));int numberOfPages = reader.getNumberOfPages();for (int i = 1; i <= numberOfPages; i++) {PdfContentByte content = stamper.getOverContent(i);PdfGState gs = new PdfGState();gs.setFillOpacity(0.5f); // 设置水印透明度content.setGState(gs);Rectangle pageSize = reader.getPageSizeWithRotation(i);float pageWidth = pageSize.getWidth();float pageHeight = pageSize.getHeight();// 设置水印间隔float xInterval = 200; // X轴间隔float yInterval = 50; // Y轴间隔// 计算水印个数int xCount = (int) Math.ceil(pageWidth / xInterval);int yCount = (int) Math.ceil(pageHeight / yInterval);// 平铺水印for (int x = 0; x < xCount; x++) {for (int y = 0; y < yCount; y++) {float xPosition = x * xInterval;float yPosition = y * yInterval;ColumnText.showTextAligned(content,Element.ALIGN_CENTER,new Phrase(watermarkText, new Font(Font.FontFamily.HELVETICA, 40)),xPosition,yPosition,45);}}}stamper.close();reader.close();} catch (Exception e) {e.printStackTrace();}}public static void addWatermarkMultiCN(String inputFile, String outputFile, String watermarkText) {try {PdfReader reader = new PdfReader(inputFile);PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));int numberOfPages = reader.getNumberOfPages();Resource resource = new ClassPathResource("simhei.ttf"); // 加载位于resources目录下的字体文件InputStream inputStream = resource.getInputStream();byte[] fontBytes = IOUtils.toByteArray(inputStream);BaseFont baseFont = BaseFont.createFont("simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, true, fontBytes, null); // 创建BaseFont对象for (int i = 1; i <= numberOfPages; i++) {PdfContentByte content = stamper.getOverContent(i);PdfGState gs = new PdfGState();gs.setFillOpacity(0.5f); // 设置水印透明度content.setGState(gs);Rectangle pageSize = reader.getPageSizeWithRotation(i);float pageWidth = pageSize.getWidth();float pageHeight = pageSize.getHeight();// 设置水印间隔float xInterval = 200; // X轴间隔float yInterval = 50; // Y轴间隔// 计算水印个数int xCount = (int) Math.ceil(pageWidth / xInterval);int yCount = (int) Math.ceil(pageHeight / yInterval);// 平铺水印for (int x = 0; x < xCount; x++) {for (int y = 0; y < yCount; y++) {float xPosition = x * xInterval;float yPosition = y * yInterval;ColumnText.showTextAligned(content,Element.ALIGN_CENTER,new Phrase(watermarkText, new Font(baseFont, 40)), // 使用创建的中文字体xPosition,yPosition,45);}}}stamper.close();reader.close();} catch (Exception e) {e.printStackTrace();}}public static void addWatermarkToPdfStream(InputStream inputStream, String watermarkText, ServletOutputStream outputStream) throws Exception {
//		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try {PdfReader reader = new PdfReader(inputStream);PdfStamper stamper = new PdfStamper(reader, outputStream);int numberOfPages = reader.getNumberOfPages();// ...(原有的水印添加逻辑)Resource resource = new ClassPathResource("/font/simhei.ttf"); // 加载位于resources目录下的字体文件InputStream inputStreamTTF = resource.getInputStream();byte[] fontBytes = IOUtils.toByteArray(inputStreamTTF);BaseFont baseFont = BaseFont.createFont("/font/simhei.ttf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, true, fontBytes, null); // 创建BaseFont对象for (int i = 1; i <= numberOfPages; i++) {PdfContentByte content = stamper.getOverContent(i);PdfGState gs = new PdfGState();gs.setFillOpacity(0.35f); // 设置水印透明度content.setGState(gs);Rectangle pageSize = reader.getPageSizeWithRotation(i);float pageWidth = pageSize.getWidth();float pageHeight = pageSize.getHeight();// 设置水印间隔float xInterval = 250; // X轴间隔float yInterval = 100; // Y轴间隔// 计算水印个数int xCount = (int) Math.ceil(pageWidth / xInterval);int yCount = (int) Math.ceil(pageHeight / yInterval);// 平铺水印for (int x = 0; x < xCount; x++) {for (int y = 0; y < yCount; y++) {float xPosition = x * xInterval;float yPosition = y * yInterval;ColumnText.showTextAligned(content,Element.ALIGN_CENTER,new Phrase(watermarkText, new Font(baseFont, 21)), // 使用创建的中文字体xPosition,yPosition,45);}}}stamper.close();reader.close();} catch (Exception e) {e.printStackTrace();throw e;}
//		return outputStream;}public static void excelToPdf(InputStream inputStream, FileOutputStream stream) throws Exception {com.itextpdf.kernel.geom.Rectangle rec = new com.itextpdf.kernel.geom.Rectangle(842, 595);Workbook workbook = new XSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(stream);com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(writer);com.itextpdf.layout.Document document = new Document(pdfDoc, new com.itextpdf.kernel.geom.PageSize(rec));com.itextpdf.layout.element.Table table =new com.itextpdf.layout.element.Table(UnitValue.createPercentArray(sheet.getRow(0).getPhysicalNumberOfCells()));DecimalFormat df = new DecimalFormat("#");for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {Row row = sheet.getRow(i);if (row == null) {continue;}if(i == 0) {table.addCell(new com.itextpdf.layout.element.Cell(1, 11).add(new com.itextpdf.layout.element.Paragraph(row.getCell(0).toString()).setTextAlignment(TextAlignment.CENTER).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));} else {for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {Cell cell = row.getCell(j);if (cell == null) {table.addCell(new com.itextpdf.layout.element.Paragraph(""));} else {
//						cell.setCellType(CellType.STRING);String val = cell.toString();if(j == 0 || j == 8){//todo 2024-05-24 liux 第一列序号单独处理一下,要不然是1.0之类的带小数位(暂时先这么处理)try{val = df.format(cell.getNumericCellValue());}catch(Exception e){}}else if(j == 10){try{BigDecimal d = new BigDecimal(val);val = String.valueOf(d.setScale(2, RoundingMode.HALF_UP));}catch(Exception e){}}Paragraph paragraph = new Paragraph(val).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(9f);if(j == 10){//todo 2024-05-24 liux  临时做法paragraph.setWidth(100);}table.addCell(paragraph);}}}}document.add(table);document.close();
//        setWaterMark(pdfDoc, document, table, stream);}/** 第二行单元格做部分合并,左对齐,第三行以下做居中** @param inputStream* @param stream* @throws Exception*/public static void excelToPdfForMergeSpecificCells(InputStream inputStream, FileOutputStream stream) throws Exception {com.itextpdf.kernel.geom.Rectangle rec = new com.itextpdf.kernel.geom.Rectangle(842, 595);Workbook workbook = new XSSFWorkbook(inputStream);Sheet sheet = workbook.getSheetAt(0);com.itextpdf.kernel.pdf.PdfWriter writer = new com.itextpdf.kernel.pdf.PdfWriter(stream);com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(writer);com.itextpdf.layout.Document document = new Document(pdfDoc, new com.itextpdf.kernel.geom.PageSize(rec));com.itextpdf.layout.element.Table table =new com.itextpdf.layout.element.Table(UnitValue.createPercentArray(sheet.getRow(0).getPhysicalNumberOfCells()));DecimalFormat df = new DecimalFormat("#");for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {Row row = sheet.getRow(i);if (row == null) {continue;}if(i == 0) {table.addCell(new com.itextpdf.layout.element.Cell(1, 12).add(new com.itextpdf.layout.element.Paragraph(row.getCell(0).toString()).setTextAlignment(TextAlignment.CENTER).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));} else if (i == 1) {// 合并前四列单元格table.addCell(new com.itextpdf.layout.element.Cell(1, 4).add(new com.itextpdf.layout.element.Paragraph(row.getCell(0).toString()).setTextAlignment(TextAlignment.LEFT).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));// 合并第五列单元格table.addCell(new com.itextpdf.layout.element.Cell(1, 1).add(new com.itextpdf.layout.element.Paragraph(row.getCell(4).toString()).setTextAlignment(TextAlignment.LEFT).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));// 合并第六列到第十列单元格table.addCell(new com.itextpdf.layout.element.Cell(1, 5).add(new com.itextpdf.layout.element.Paragraph(row.getCell(5).toString()).setTextAlignment(TextAlignment.LEFT).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));// 合并剩下单元格table.addCell(new com.itextpdf.layout.element.Cell(1, 2).add(new com.itextpdf.layout.element.Paragraph(row.getCell(10).toString()).setTextAlignment(TextAlignment.LEFT).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(10f)));} else {for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {Cell cell = row.getCell(j);if (cell == null) {table.addCell(new com.itextpdf.layout.element.Paragraph("").setTextAlignment(TextAlignment.CENTER));} else {
//						cell.setCellType(CellType.STRING);String val = cell.toString();if(j == 0 || j ==6 || j == 9){//todo 2024-05-24 liux 第一列序号单独处理一下,要不然是1.0之类的带小数位(暂时先这么处理)try{val = df.format(cell.getNumericCellValue());}catch(Exception e){}}else if(j == 7 || j == 8 || j == 10 ||  j == 11){try{BigDecimal d = new BigDecimal(val);val = String.valueOf(d.setScale(2, RoundingMode.HALF_UP));}catch(Exception e){}}Paragraph paragraph = new Paragraph(val).setFont(PdfFontFactory.createFont(FONT_SIMFANG_PATH, ENCODING)).setFontSize(9f);if(j == 4){//todo 2024-05-24 liux  临时做法paragraph.setWidth(150);}table.addCell(paragraph).setTextAlignment(TextAlignment.CENTER);}}}}document.add(table);document.close();
//        setWaterMark(pdfDoc, document, table, stream);}public static void addWatermarkExample(List<File> files) {// 在这里编写添加水印的代码逻辑,使用上面提到的添加水印的示例代码for (File file : files) {addWatermark(file.getPath(), file.getPath(), "Watermark Text");}}//	public static void main(String[] args) {
//		String inputFile = "D:\\Downloads\\123.pdf";
//		String outputFile = "D:\\Downloads\\456.pdf";
//		String watermarkText = "这是中文水印";
//
//		addWatermarkMultiCN(inputFile, outputFile, watermarkText);
//
//
//		String outputFileStream = "D:\\Downloads\\789.pdf";
//		String watermarkText02 = "这是读取流返回流";
//
//		try (InputStream input = new FileInputStream(inputFile)) {
//			ByteArrayOutputStream output = addWatermarkToPdfStream(input, watermarkText02);
//			try (OutputStream fileOutput = new FileOutputStream(outputFileStream)) {
//				output.writeTo(fileOutput);
//			}
//		} catch (IOException e) {
//			e.printStackTrace();
//		}
//	}
}

第二种

package org.springblade.common.tool;import cn.hutool.core.collection.CollUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import lombok.experimental.UtilityClass;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;@UtilityClass
public class ExcelToPdfUtil {public static void main(String[] args) throws FileNotFoundException {String excelPath = "D:\\无用\\test.xlsx";String pdfPath = "D:\\无用\\test02.pdf";try {ExcelToPdfUtil.excelToPdf(excelPath, pdfPath, ".xlsx");System.out.println("Excel转换为PDF成功!PDF文件路径:" + pdfPath);} catch (Exception e) {System.err.println("Excel转换为PDF失败:" + e.getMessage());e.printStackTrace();}}public static void excelToPdf(String excelPath, String pdfPath, String excelSuffix) {try (InputStream in = Files.newInputStream(Paths.get(excelPath));OutputStream out = Files.newOutputStream(Paths.get(pdfPath))) {ExcelToPdfUtil.excelToPdf(in, out, excelSuffix);} catch (Exception e) {e.printStackTrace();}}/*** Excel转PDF并写入输出流** @param inStream    Excel输入流* @param outStream   PDF输出流* @param excelSuffix Excel类型 .xls 和 .xlsx* @throws Exception 异常信息*/public static void excelToPdf(InputStream inStream, OutputStream outStream, String excelSuffix) throws Exception {// 输入流转workbook,获取sheetSheet sheet = getPoiSheetByFileStream(inStream, 0, excelSuffix);// 获取列宽度占比float[] widths = getColWidth(sheet);PdfPTable table = new PdfPTable(widths);table.setWidthPercentage(100);int colCount = widths.length;//设置基本字体BaseFont baseFont = BaseFont.createFont("C:\\Windows\\Fonts\\simsun.ttc,0", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);// 遍历行for (int rowIndex = sheet.getFirstRowNum(); rowIndex <= sheet.getLastRowNum(); rowIndex++) {Row row = sheet.getRow(rowIndex);if (Objects.isNull(row)) {// 插入空对象for (int i = 0; i < colCount; i++) {table.addCell(createPdfPCell(null, 0, 13f, null));}} else {// 遍历单元格for (int columnIndex = 0; (columnIndex < row.getLastCellNum() || columnIndex < colCount) && columnIndex > -1; columnIndex++) {PdfPCell pCell = excelCellToPdfCell(sheet, row.getCell(columnIndex), baseFont);// 是否合并单元格if (isMergedRegion(sheet, rowIndex, columnIndex)) {int[] span = getMergedSpan(sheet, rowIndex, columnIndex);//忽略合并过的单元格boolean mergedCell = span[0] == 1 && span[1] == 1;if (mergedCell) {continue;}pCell.setRowspan(span[0]);pCell.setColspan(span[1]);}table.addCell(pCell);}}}// 初始化PDF文档对象createPdfTableAndWriteDocument(outStream, table);}/*** 单元格转换,poi cell 转换为 itext cell** @param sheet     poi sheet页* @param excelCell poi 单元格* @param baseFont  基础字体* @return com.itextpdf.text.pdf.PdfPCell*/private static PdfPCell excelCellToPdfCell(Sheet sheet, Cell excelCell, BaseFont baseFont) throws Exception {if (Objects.isNull(excelCell)) {return createPdfPCell(null, 0, 13f, null);}int rowIndex = excelCell.getRowIndex();int columnIndex = excelCell.getColumnIndex();// 图片信息List<PicturesInfo> infos = getAllPictureInfos(sheet, rowIndex, rowIndex, columnIndex, columnIndex, false);PdfPCell pCell;if (CollUtil.isNotEmpty(infos)) {pCell = new PdfPCell(Image.getInstance(infos.get(0).getPictureData()));} else {Font excelFont = getExcelFont(sheet, excelCell);//设置单元格字体com.itextpdf.text.Font pdFont = new com.itextpdf.text.Font(baseFont, excelFont.getFontHeightInPoints(), excelFont.getBold() ? 1 : 0, BaseColor.BLACK);Integer border = hasBorder(excelCell) ? null : 0;String excelCellValue = getExcelCellValue(excelCell);pCell = createPdfPCell(excelCellValue, border, excelCell.getRow().getHeightInPoints(), pdFont);}// 水平居中pCell.setHorizontalAlignment(getHorAlign(excelCell.getCellStyle().getAlignment().getCode()));// 垂直对齐pCell.setVerticalAlignment(getVerAlign(excelCell.getCellStyle().getVerticalAlignment().getCode()));return pCell;}/*** 创建pdf文档,并添加表格** @param outStream 输出流,目标文档* @param table     表格* @throws DocumentException 异常信息*/private static void createPdfTableAndWriteDocument(OutputStream outStream, PdfPTable table) throws DocumentException {//设置pdf纸张大小 PageSize.A4 A4横向Document document = new Document(new RectangleReadOnly(842.0F, 595.0F));PdfWriter.getInstance(document, outStream);//设置页边距 宽document.setMargins(10, 10, 10, 10);document.open();document.add(table);document.close();}/*** Excel文档输入流转换为对应的workbook及获取对应的sheet** @param inputStream Excel文档输入流* @param sheetNo     sheet编号,默认0 第一个sheet* @param excelSuffix 文件类型 .xls和.xlsx* @return poi sheet* @throws IOException 异常*/public static Sheet getPoiSheetByFileStream(InputStream inputStream, int sheetNo, String excelSuffix) throws IOException {Workbook workbook;if (excelSuffix.endsWith(".xls")) {workbook = new HSSFWorkbook(inputStream);} else {workbook = new XSSFWorkbook(inputStream);}return workbook.getSheetAt(sheetNo);}/*** 创建itext pdf 单元格** @param content       单元格内容* @param border        边框* @param minimumHeight 高度* @param pdFont        字体* @return pdf cell*/private static PdfPCell createPdfPCell(String content, Integer border, Float minimumHeight, com.itextpdf.text.Font pdFont) {String contentValue = content == null ? "" : content;com.itextpdf.text.Font pdFontNew = pdFont == null ? new com.itextpdf.text.Font() : pdFont;PdfPCell pCell = new PdfPCell(new Phrase(contentValue, pdFontNew));if (Objects.nonNull(border)) {pCell.setBorder(border);}if (Objects.nonNull(minimumHeight)) {pCell.setMinimumHeight(minimumHeight);}return pCell;}/*** excel垂直对齐方式映射到pdf对齐方式*/private static int getVerAlign(int align) {switch (align) {case 2:return com.itextpdf.text.Element.ALIGN_BOTTOM;case 3:return com.itextpdf.text.Element.ALIGN_TOP;default:return com.itextpdf.text.Element.ALIGN_MIDDLE;}}/*** excel水平对齐方式映射到pdf水平对齐方式*/private static int getHorAlign(int align) {switch (align) {case 1:return com.itextpdf.text.Element.ALIGN_LEFT;case 3:return com.itextpdf.text.Element.ALIGN_RIGHT;default:return com.itextpdf.text.Element.ALIGN_CENTER;}}/*============================================== POI获取图片及文本内容工具方法 ==============================================*//*** 获取字体** @param sheet excel 转换的sheet页* @param cell  单元格* @return 字体*/private static Font getExcelFont(Sheet sheet, Cell cell) {// xlsif (sheet instanceof HSSFSheet) {Workbook workbook = sheet.getWorkbook();return ((HSSFCell) cell).getCellStyle().getFont(workbook);}// xlsxreturn ((XSSFCell) cell).getCellStyle().getFont();}/*** 判断excel单元格是否有边框*/private static boolean hasBorder(Cell excelCell) {short top = excelCell.getCellStyle().getBorderTop().getCode();short bottom = excelCell.getCellStyle().getBorderBottom().getCode();short left = excelCell.getCellStyle().getBorderLeft().getCode();short right = excelCell.getCellStyle().getBorderRight().getCode();return top + bottom + left + right > 2;}/*** 判断单元格是否是合并单元格*/private static boolean isMergedRegion(Sheet sheet, int row, int column) {int sheetMergeCount = sheet.getNumMergedRegions();for (int i = 0; i < sheetMergeCount; i++) {CellRangeAddress range = sheet.getMergedRegion(i);int firstColumn = range.getFirstColumn();int lastColumn = range.getLastColumn();int firstRow = range.getFirstRow();int lastRow = range.getLastRow();if (row >= firstRow && row <= lastRow) {if (column >= firstColumn && column <= lastColumn) {return true;}}}return false;}/*** 计算合并单元格合并的跨行跨列数*/private static int[] getMergedSpan(Sheet sheet, int row, int column) {int sheetMergeCount = sheet.getNumMergedRegions();int[] span = {1, 1};for (int i = 0; i < sheetMergeCount; i++) {CellRangeAddress range = sheet.getMergedRegion(i);int firstColumn = range.getFirstColumn();int lastColumn = range.getLastColumn();int firstRow = range.getFirstRow();int lastRow = range.getLastRow();if (firstColumn == column && firstRow == row) {span[0] = lastRow - firstRow + 1;span[1] = lastColumn - firstColumn + 1;break;}}return span;}/*** 获取excel中每列宽度的占比*/private static float[] getColWidth(Sheet sheet) {int rowNum = getMaxColRowNum(sheet);Row row = sheet.getRow(rowNum);int cellCount = row.getPhysicalNumberOfCells();int[] colWidths = new int[cellCount];int sum = 0;for (int i = row.getFirstCellNum(); i < cellCount; i++) {Cell cell = row.getCell(i);if (cell != null) {colWidths[i] = sheet.getColumnWidth(i);sum += sheet.getColumnWidth(i);}}float[] colWidthPer = new float[cellCount];for (int i = row.getFirstCellNum(); i < cellCount; i++) {colWidthPer[i] = (float) colWidths[i] / sum * 100;}return colWidthPer;}/*** 获取excel中列数最多的行号*/private static int getMaxColRowNum(Sheet sheet) {int rowNum = 0;int maxCol = 0;for (int r = sheet.getFirstRowNum(); r < sheet.getPhysicalNumberOfRows(); r++) {Row row = sheet.getRow(r);if (row != null && maxCol < row.getPhysicalNumberOfCells()) {maxCol = row.getPhysicalNumberOfCells();rowNum = r;}}return rowNum;}/*** poi 根据单元格类型获取单元格内容** @param excelCell poi单元格* @return 单元格内容文本*/public static String getExcelCellValue(Cell excelCell) {if (excelCell == null) {return "";}// 判断数据的类型CellType cellType = excelCell.getCellType();if (cellType == CellType.STRING) {return excelCell.getStringCellValue();}if (cellType == CellType.BOOLEAN) {return String.valueOf(excelCell.getBooleanCellValue());}if (cellType == CellType.FORMULA) {return excelCell.getCellFormula();}if (cellType == CellType.NUMERIC) {//short s = excelCell.getCellStyle().getDataFormat();if (DateUtil.isCellDateFormatted(excelCell)) {// 处理日期格式、时间格式SimpleDateFormat sdf;// 验证short值if (excelCell.getCellStyle().getDataFormat() == 14) {sdf = new SimpleDateFormat("yyyy/MM/dd");} else if (excelCell.getCellStyle().getDataFormat() == 21) {sdf = new SimpleDateFormat("HH:mm:ss");} else if (excelCell.getCellStyle().getDataFormat() == 22) {sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");} else {throw new RuntimeException("日期格式错误!!!");}Date date = excelCell.getDateCellValue();return sdf.format(date);} else if (excelCell.getCellStyle().getDataFormat() == 0) {//处理数值格式DataFormatter formatter = new DataFormatter();return formatter.formatCellValue(excelCell);}}if (cellType == CellType.ERROR) {return "非法字符";}return "";}/*** 获取sheet内的所有图片信息** @param sheet        sheet表* @param onlyInternal 单元格内部* @return 照片集合* @throws Exception 异常*/public static List<PicturesInfo> getAllPictureInfos(Sheet sheet, boolean onlyInternal) throws Exception {return getAllPictureInfos(sheet, null, null, null, null, onlyInternal);}/*** 根据sheet和单元格信息获取图片** @param sheet        sheet表* @param minRow       最小行* @param maxRow       最大行* @param minCol       最小列* @param maxCol       最大列* @param onlyInternal 是否内部* @return 图片集合* @throws Exception 异常*/public static List<PicturesInfo> getAllPictureInfos(Sheet sheet, Integer minRow, Integer maxRow, Integer minCol,Integer maxCol, boolean onlyInternal) throws Exception {if (sheet instanceof HSSFSheet) {return getXLSAllPictureInfos((HSSFSheet) sheet, minRow, maxRow, minCol, maxCol, onlyInternal);} else if (sheet instanceof XSSFSheet) {return getXLSXAllPictureInfos((XSSFSheet) sheet, minRow, maxRow, minCol, maxCol, onlyInternal);} else {throw new Exception("未处理类型,没有为该类型添加:GetAllPicturesInfos()扩展方法!");}}private static List<PicturesInfo> getXLSAllPictureInfos(HSSFSheet sheet, Integer minRow, Integer maxRow,Integer minCol, Integer maxCol, Boolean onlyInternal) {List<PicturesInfo> picturesInfoList = new ArrayList<>();HSSFShapeContainer shapeContainer = sheet.getDrawingPatriarch();if (shapeContainer == null) {return picturesInfoList;}List<HSSFShape> shapeList = shapeContainer.getChildren();for (HSSFShape shape : shapeList) {if (shape instanceof HSSFPicture && shape.getAnchor() instanceof HSSFClientAnchor) {HSSFPicture picture = (HSSFPicture) shape;HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();if (isInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.getRow1(), anchor.getRow2(),anchor.getCol1(), anchor.getCol2(), onlyInternal)) {HSSFPictureData pictureData = picture.getPictureData();picturesInfoList.add(new PicturesInfo().setMinRow(anchor.getRow1()).setMaxRow(anchor.getRow2()).setMinCol(anchor.getCol1()).setMaxCol(anchor.getCol2()).setPictureData(pictureData.getData()).setExt(pictureData.getMimeType()));}}}return picturesInfoList;}private static List<PicturesInfo> getXLSXAllPictureInfos(XSSFSheet sheet, Integer minRow, Integer maxRow,Integer minCol, Integer maxCol, Boolean onlyInternal) {List<PicturesInfo> picturesInfoList = new ArrayList<>();List<POIXMLDocumentPart> documentPartList = sheet.getRelations();for (POIXMLDocumentPart documentPart : documentPartList) {if (documentPart instanceof XSSFDrawing) {XSSFDrawing drawing = (XSSFDrawing) documentPart;List<XSSFShape> shapes = drawing.getShapes();for (XSSFShape shape : shapes) {if (shape instanceof XSSFPicture) {XSSFPicture picture = (XSSFPicture) shape;XSSFClientAnchor anchor = picture.getPreferredSize();if (isInternalOrIntersect(minRow, maxRow, minCol, maxCol, anchor.getRow1(), anchor.getRow2(),anchor.getCol1(), anchor.getCol2(), onlyInternal)) {XSSFPictureData pictureData = picture.getPictureData();picturesInfoList.add(new PicturesInfo().setMinRow(anchor.getRow1()).setMaxRow(anchor.getRow2()).setMinCol(anchor.getCol1()).setMaxCol(anchor.getCol2()).setPictureData(pictureData.getData()).setExt(pictureData.getMimeType()));}}}}}return picturesInfoList;}private static boolean isInternalOrIntersect(Integer rangeMinRow, Integer rangeMaxRow, Integer rangeMinCol,Integer rangeMaxCol, int pictureMinRow, int pictureMaxRow, int pictureMinCol, int pictureMaxCol,Boolean onlyInternal) {int _rangeMinRow = rangeMinRow == null ? pictureMinRow : rangeMinRow;int _rangeMaxRow = rangeMaxRow == null ? pictureMaxRow : rangeMaxRow;int _rangeMinCol = rangeMinCol == null ? pictureMinCol : rangeMinCol;int _rangeMaxCol = rangeMaxCol == null ? pictureMaxCol : rangeMaxCol;if (onlyInternal) {return (_rangeMinRow <= pictureMinRow && _rangeMaxRow >= pictureMaxRow && _rangeMinCol <= pictureMinCol&& _rangeMaxCol >= pictureMaxCol);} else {return ((Math.abs(_rangeMaxRow - _rangeMinRow) + Math.abs(pictureMaxRow - pictureMinRow) >= Math.abs(_rangeMaxRow + _rangeMinRow - pictureMaxRow - pictureMinRow))&& (Math.abs(_rangeMaxCol - _rangeMinCol) + Math.abs(pictureMaxCol - pictureMinCol) >= Math.abs(_rangeMaxCol + _rangeMinCol - pictureMaxCol - pictureMinCol)));}}/*** 图片基本信息*/private class PicturesInfo {private int minRow;private int maxRow;private int minCol;private int maxCol;private String ext;private byte[] pictureData;public PicturesInfo() {}public byte[] getPictureData() {return pictureData;}public PicturesInfo setPictureData(byte[] pictureData) {this.pictureData = pictureData;return this;}public int getMinRow() {return minRow;}public PicturesInfo setMinRow(int minRow) {this.minRow = minRow;return this;}public int getMaxRow() {return maxRow;}public PicturesInfo setMaxRow(int maxRow) {this.maxRow = maxRow;return this;}public int getMinCol() {return minCol;}public PicturesInfo setMinCol(int minCol) {this.minCol = minCol;return this;}public int getMaxCol() {return maxCol;}public PicturesInfo setMaxCol(int maxCol) {this.maxCol = maxCol;return this;}public String getExt() {return ext;}public PicturesInfo setExt(String ext) {this.ext = ext;return this;}//有中间文件的 excel转pdf再加水印
//		public static void main(String[] args) throws FileNotFoundException {
//			String inputFile = "D:\\Downloads\\123.xlsx";
//			String outputFile = "D:\\Downloads\\999.pdf";
//			String watermarkedFile = "D:\\Downloads\\999_watermarked.pdf";
//
//			// 获取inputFile的文件输出流
//			FileInputStream fileInputStream = new FileInputStream(inputFile);
//
//			try {
//				// 创建输出流
//				OutputStream outputStream = new FileOutputStream(outputFile);
//
//				// 调用excelToPdf方法将Excel转换为PDF并写入输出流
//				excelToPdf(fileInputStream, outputStream, "xlsx");
//
//				//这个outputStream将里面的数据转成inputStream,后续要再做一次处理
//
//
//				// 关闭输入流和输出流
//				fileInputStream.close();
//
//				//==============================加水印=================================
//				// 创建输入流和输出流
//				FileInputStream pdfInputStream = new FileInputStream(outputFile);
//				ByteArrayOutputStream watermarkedOutputStream = PDFWatermarkExample.addWatermarkToPdfStream(pdfInputStream, "excel转PDF再加水印");
//
//				// 将加水印后的PDF写入文件
//				FileOutputStream watermarkedFileOutputStream = new FileOutputStream(watermarkedFile);
//				watermarkedOutputStream.writeTo(watermarkedFileOutputStream);
//
//				// 关闭输入流和输出流
//				pdfInputStream.close();
//				watermarkedOutputStream.close();
//				watermarkedFileOutputStream.close();
//
//
//				outputStream.close();
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//		}/*** 通过使用内存流,可以直接从Excel文件转换为带水印的PDF文件,而不需要生成中间文件。* @param args* @throws FileNotFoundException*/public static void main(String[] args) throws FileNotFoundException {String inputFile = "D:\\Downloads\\123.xlsx";String watermarkedFile = "D:\\Downloads\\999_watermarked.pdf";try {// 创建输入流FileInputStream fileInputStream = new FileInputStream(inputFile);// 创建输出流ByteArrayOutputStream pdfOutputStream = new ByteArrayOutputStream();// 调用excelToPdf方法将Excel转换为PDF并写入输出流excelToPdf(fileInputStream, pdfOutputStream, "xlsx");// 关闭输入流fileInputStream.close();//==============================加水印=================================// 创建输入流ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfOutputStream.toByteArray());ByteArrayOutputStream watermarkedOutputStream = PDFWatermarkExample.addWatermarkToPdfStream(pdfInputStream, "excel转PDF再加水印");// 将加水印后的PDF写入文件FileOutputStream watermarkedFileOutputStream = new FileOutputStream(watermarkedFile);watermarkedOutputStream.writeTo(watermarkedFileOutputStream);// 关闭输入流和输出流pdfInputStream.close();watermarkedOutputStream.close();watermarkedFileOutputStream.close();} catch (Exception e) {e.printStackTrace();}}}
}

对比于 excelToPdf 两个方法

这两种导出 PDF 的方法有几个显著的区别:

  1. 使用的 PDF 库不同

    • 第一种方法使用的是 iText 7 库,通过构建 PdfDocument 和 Document 对象来生成 PDF 文件。
    • 第二种方法使用的是 iText 5 库,通过创建 PdfPTable 和 PdfPCell 对象来构建 PDF 表格并写入到输出流中。
  2. 样式设置不同

    • 第一种方法中,设置了文档的大小、字体、字体大小等属性,并使用 iText 7 提供的方式创建表格和单元格,进行文本对齐等操作。
    • 第二种方法中,设置了基本字体、单元格的行跃高度、字体大小等属性,通过 iText 5 的 PdfPTable 和 PdfPCell 对象来构建表格并填充内容。
  3. 处理数据不同

    • 第一种方法中,对第一行数据进行特殊处理,设置为居中显示,并设置不同的字体和字体大小。
    • 第二种方法中,遍历 Excel 中的每一行和单元格,根据单元格的内容创建 PdfPCell,并根据是否为合并单元格设置行和列的跨度。
  4. 版本兼容性

    • iText 7 和 iText 5 是不同版本的 iText 库,两种方法使用的 API 和功能略有不同,因此在处理 PDF 导出时会有一些差异。

总的来说,两种方法在处理 PDF 导出时的逻辑、样式设置和数据处理上有所不同,主要取决于所使用的 iText 版本和对应的 API

相关文章:

java分别使用 iText 7 库和iText 5 库 将excel转成PDF导出,以及如何对excel转PDF合并单元格

第一种 package com.junfun.pms.report.util;import com.itextpdf.kernel.font.PdfFontFactory; import com.itextpdf.layout.Document; import com.itextpdf.layout.element.Paragraph; import com.itextpdf.layout.property.TextAlignment; import com.itextpdf.layout.prop…...

Java特性之设计模式【访问者模式】

一、访问者模式 概述 在访问者模式&#xff08;Visitor Pattern&#xff09;中&#xff0c;我们使用了一个访问者类&#xff0c;它改变了元素类的执行算法。通过这种方式&#xff0c;元素的执行算法可以随着访问者改变而改变。这种类型的设计模式属于行为型模式。根据模式&…...

【教师资格证考试综合素质——法律专项】未成年人保护法笔记以及练习题

《中华人民共和国未成年人保护法》 目录 第一章 总 则 第二章 家庭保护 第三章 学校保护 第四章 社会保护 第五章 网络保护 第六章 政府保护 第七章 司法保护 第八章 法律责任 第九章 附 则 介一&#xff0e;首次颁布&#xff1a;第一部《中华人民共和国未成年人保护法…...

6.19作业

TCP服务器 #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <unistd.h> #include <arpa/inet.h> #include <netinet/in.h> #include <string.h>#define PORT 8888 #define IP "192.168.124.39&q…...

java 线程之间通信-volatile 和 synchronized

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…...

资源宝库网站!人人必备的神器!

面对网络中海量的内容&#xff0c;一个高效、便捷的网络导航工具&#xff0c;可以帮助我们快速查找使用网络资源。无论是职场精英还是学生党&#xff0c;使用导航网站都可以帮助我们提升效率。下面小编就来和大家分享一款资源宝库网站-办公人导航-实用的办公生活导航网站&#…...

Redis实战—优惠卷秒杀(锁/事务/代理对象的应用)

本博客为个人学习笔记&#xff0c;学习网站与详细见&#xff1a;黑马程序员Redis入门到实战 P50 - P54 目录 优惠卷秒杀下单功能实现 超卖问题 悲观锁与乐观锁 实现CAS法乐观锁 一人一单功能实现 代码优化 代码细节分析 优惠卷秒杀下单功能实现 ​ ​ Controller层…...

HTML星空特效

目录 写在前面 完整代码 代码分析 运行效果 系列文章 写在后面 写在前面 100行代码实现HTML星空特效。 完整代码 全部代码如下。 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&g…...

银行数仓项目实战(四)--了解银行业务(存款)

文章目录 项目准备存款活期定期整存整取零存整取存本取息教育储蓄定活两便通知存款 对公存款对公账户协议存款 利率 项目准备 &#xff08;贴源层不必写到项目文档&#xff0c;因为没啥操作没啥技术&#xff0c;只是数据。&#xff09; 可以看到&#xff0c;银行的贴源层并不紧…...

MySQL版本发布模型

MySQL 8.0 之后使用了新的版本控制和发布模型&#xff0c;分为两个主线&#xff1a;长期支持版&#xff08;LTS&#xff09;以及创新版。这两种版本都包含了缺陷修复和安全修复&#xff0c;都可以用于生产环境。 下图是 MySQL 的版本发布计划&#xff1a; 长期支持版 MySQL…...

java: 不兼容的类型: org.apache.xmlbeans.XmlObject无法转换为x2006.main.CTRow

我使用的xmlbeans版本是5.0&#xff0c;使用xmlbeans包做转换时&#xff0c;报错&#xff0c;正如标题显示得那样 解决办法 额外再引入下面的jar包 <dependency><groupId>org.apache.xmlbeans</groupId><artifactId>xmlbeans</artifactId><…...

内容时代:品牌如何利用社交平台精准触达用户

还记得学生时代老师教写作文的时候常说的一句话就是“开头质量决定了阅卷老师想不想花精力去读&#xff0c;而内容质量决定了她愿不愿意给你判高分”这个世界仿若一个巨大的圆&#xff0c;同样的逻辑放在任何地方好像都能适用。在品牌营销中&#xff0c;内容已成为品牌与消费者…...

推荐4款PC端黑科技工具,快来看看,建议收藏

Thunderbird Thunderbird 是由 Mozilla 基金会开发的一款免费且开源的电子邮件客户端&#xff0c;支持 Windows、macOS、Linux 等多种操作系统。它不仅可以用于发送和接收电子邮件&#xff0c;还可以作为新闻阅读器、聊天工具以及日历应用。 Thunderbird 提供了丰富的功能&…...

汉化版PSAI全面测评,探索国产AI绘画软件的创新力量

引言 随着AI技术的飞速发展&#xff0c;图像处理和绘画领域迎来了新的变革。作为一名AIGC测评博主&#xff0c;今天我们测评的是一款国产AI绘画软件——StartAI&#xff0c;一句话总结&#xff1a;它不仅在技术上毫不逊色于国际大牌&#xff0c;更在用户体验和本地化服务上做到…...

LeetCode | 709.转换成小写字母

这道题可以用api也可以自己实现&#xff0c;都不难&#xff0c;大小字母之前相差了32&#xff0c;检查到大写字母时加上32即可 class Solution(object):def toLowerCase(self, s):""":type s: str:rtype: str"""return s.lower()class Solution…...

洗地机哪个品牌比较好?四款好用靠谱的优质洗地机推荐

随着现代生活节奏的加快&#xff0c;家庭清洁成了一项耗时且繁琐的任务。洗地机凭借其智能化和高效的清洁能力&#xff0c;越来越受到大家的青睐。然而&#xff0c;市场上各种品牌和型号琳琅满目&#xff0c;让人眼花缭乱。为了帮助大家在众多选择中找到心仪的产品&#xff0c;…...

java:spring actuator添加自定义endpoint

# 项目代码资源&#xff1a; 可能还在审核中&#xff0c;请等待。。。 https://download.csdn.net/download/chenhz2284/89437274 # 项目代码 【pom.xml】 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId&…...

LeetCode88-删除有序数组中的重复项

题目 给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 代…...

SpringBoot Starter 通用接口加密组件(防篡改)+ RequestBodyAdvice和ResponseBodyAdvice原理

防篡改&#xff1a; 如何保证接口安全&#xff0c;做到防篡改防重放&#xff1f;_接口防止串改-CSDN博客 接口安全设计之防篡改和防重放_接口防篡改机制-CSDN博客 参考博客&#xff1a; RequestBodyAdvice和ResponseBodyAdvice原理详解-CSDN博客 SpringBoot Starter 通用接口…...

delphi 如何使用TEdgeBrowser组件以及打包环境在其他主机上运行

不管开发环境还是第三方环境先安装运行时库&#xff1a;Microsoft Edge WebView2 | Microsoft Edge Developer 开发环境可以直接通过&#xff1a; delphi IDE安装 安装完毕后进入到指定路径&#xff0c;复制里面的WebView2Loader.dll到你要开发的程序根目录&#xff1a; 大致路…...

Sui的Fastcrypto加密库刷新速度记录

Sui使用的加密库Fastcrypto打破了许多速度记录&#xff0c;Mysten Labs在基准测试和安全分析中的工作修复了许多安全漏洞&#xff0c;同时通过识别新的优化技巧为创新开辟了道路。 最近在伦敦帝国理工学院举行的国际性能工程会议&#xff08;ICPE&#xff09;基准测试研讨会上…...

Malformed \uxxxx encoding或Maven server structure problem问题解决

问题描述&#xff1a; idea运行项目时, 报错如下: [ERROR] Malformed \uxxxx encoding. [ERROR] Maven server structure problem [ERROR] Malformed \uxxxx encoding. 解决方法总结 先说一下解决方法无非是下面几种 1、先检查项目的.properties、.yml 、pom.xml、logback等…...

Sui主网升级至V1.27.2版本

其他升级要点如下所示&#xff1a; 重点&#xff1a; #17245 增加了一个新的协议版本&#xff0c;并在开发网络上启用了Move枚举。 JSON-RPC #17245: 在返回的JSON-RPC结果中增加了对Move枚举值的支持。 GraphQL #17245: 增加了对Move枚举值和类型的支持。 CLI #179…...

Cheat Engine 学习

文章目录 Exact Value scanning任务实现步骤Unknown initial value任务实现步骤原理说明Floating points任务实现步骤原理说明Code finder任务实现步骤原理说明Pointers任务实现步骤原理说明Change Pointer 操作:Active(活跃状态)和数值修改:Code Injection任务概述实现步骤…...

【千帆AppBuilder】你有一封邮件待查收|未来的我,你好吗?欢迎体验AI应用《未来信使》

我在百度智能云千帆AppBuilder开发了一款AI原生应用&#xff0c;快来使用吧&#xff01;「未来信使」&#xff1a;https://appbuilder.baidu.com/s/Q1VPg 目录 背景人工智能未来的信 未来信使功能介绍Prompt组件 千帆社区主要功能AppBuilderModelBuilder详细信息 推荐文章 未来…...

【案例分析】一文讲清楚SaaS产品运营的六大杠杆是什么?具体怎么运用?

在SaaS&#xff08;软件即服务&#xff09;行业&#xff0c;如何快速获取用户并实现持续增长一直是企业关注的重点。近年来&#xff0c;分销裂变策略因其高效性和低成本特性&#xff0c;成为许多SaaS企业实现快速增长的秘诀。下面&#xff0c;我们将通过一个具体的案例来剖析成…...

系统架构——Spring Framework

目录 &#xff08;1&#xff09;基本介绍 &#xff08;2&#xff09;基本发展历史 &#xff08;3&#xff09;了解和学习 Spring 4.x 系列的系统架构 1、第一个模块&#xff1a;做核心容器&#xff08;Core Contaner&#xff09; 2、第二个模块&#xff1a;AOP与Aspects(这…...

Zig标准库:最全数据结构深度解析(1)

最近新闻看到17岁中专女生拿下阿里全球数学竞赛第12名。咱们学习标准库中的数据结构是和学习数学是一脉相承的&#xff0c;结构体很多&#xff0c;也非常枯燥&#xff0c;但是不能全面解读过一遍&#xff0c;你很难写出合理的代码。所以&#xff0c;这一章节我们开始深度解析Zi…...

什么是 Linux From Scratch (LFS)?

Linux From Scratch (LFS) 是一个项目和一本书&#xff0c;指导用户从头开始构建自己的自定义Linux系统&#xff0c;而不是使用现成的Linux发行版。LFS项目由 Gerard Beekmans 在1999年创建&#xff0c;旨在帮助用户了解Linux的内部工作原理&#xff0c;并提供对系统的完全控制…...

常见的宽基指数基金

指数基金投资指南 ❝ 这篇博客里面的内容主要来自于银行螺丝钉的《定投十年&#xff0c;财务自由》和《指数基金投资指南》这两本书中章“常见的宽基指数”&#xff0c;最近第三次读这本书&#xff0c;打算做一点笔记加深自己的印象。 博客中很多内容是从书中摘抄的&#xff0c…...

ui设计的发展趋势/网站优化排名软件

写于2019年1月10日天添书香阁开更前的历史记录1今年开始的读书笔记&#xff0c;准备从构建多元思维模型的角度&#xff0c;分析每本书在各自思维模型领域赋予的价值&#xff0c;探索每个思维模型在现实生活中的用法以及与其他思维模型的结合。目标通过5-10年时间&#xff0c;架…...

怎么做国外的网站/惠州seo快速排名

言之易而为之难&#xff0c;学习大数据之图计算&#xff0c;就是从“浊”中找出“静”的规律&#xff0c;达到“清”的境界&#xff1b;从“安”中找出“生”的状态。 转发请标明原文地址&#xff1a;原文地址 概述 GraphX是Spark中用于图和图计算的组件&#xff0c;GraphX通…...

哪些做图片赚钱的网站/自动搜索关键词软件

命令帮助信息获取sh 执行脚本-x选项来查看这个脚本执行过程的[rootlocalhost ~]# sh 1.sh [rootlocalhost ~]# sh -x 1.sh [rootlocalhost ~]# ./1.sh-n 只读取shell脚本&#xff0c;但不实际执行-x 进入跟踪方式&#xff0c;显示所执行的每一条命令echo将输入的字符串送往标准…...

专业免费建站/企业网站推广

返回值有两种状态&#xff1a;true 和 false true 表示没被注册 &#xff1a; 12345678900也是true&#xff0c; 满足11位的就可以被检测&#xff0c; 并不能检测手机号本身是否有效&#xff0c; 但是正常手机号&#xff0c;没被注册就是true。 false 表示已经注册或者手机号…...

江苏省做网站/seo营销外包

概要&#xff1a; DelegatingFilterProxy(顾名思义是授权过滤器代理类)类不是针对SHIRO出现的&#xff0c;是SHIRO的org.apache.shiro.spring.web.ShiroFilterFactoryBean 使用到了SPRING这个类提供功能。这个类使SPRING容器中的BEAN可以在WEB.XML中配置为FILTER&#xff0c;并…...

对外贸网站建设的建议/企业宣传方式有哪些

cookie cookie: 获取百度翻译某个词条的结果 一定要对start_requests方法进行重写。 两种解决方案&#xff1a; 1. Request&#xff08;&#xff09;方法中给method属性赋值成post2. FormRequest&#xff08;&#xff09;进行post请求的发送 爬虫相关操作 # -*- coding: utf-8 …...