Skip to content

Commit

Permalink
2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ririv committed Feb 3, 2025
1 parent 8828d44 commit e4424b5
Show file tree
Hide file tree
Showing 26 changed files with 484 additions and 309 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
![interface](image/screenshot.png)

## 使用方式

1. 拖动PDF文件到窗口
2. 写入目录文本,格式在下面
3. 设定 页面偏移量=PDF中的页码–原书的页码
Expand Down Expand Up @@ -55,6 +56,7 @@

![screenvideo_1](image/screenvideo_1.gif)

[1.0版本使用说明移步这里](https://zhuanlan.zhihu.com/p/390719305)


### Tips
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public interface OutlineProcessor {
当再次使用上次被打开的pdfDoc时,会报错head not found
因此这里调用函数时打开doc,并在函数中即时关闭它
*/
void setContents(Bookmark rootBookmark, String srcFilePath, String destFilePath, PdfViewScaleType scaleType) throws IOException;
void setContents(Bookmark rootBookmark, String srcFilePath, String destFilePath, ViewScaleType scaleType) throws IOException;

String getContents(String srcFilePath, int offset) throws IOException;

Expand Down
31 changes: 31 additions & 0 deletions src/main/java/com/ririv/quickoutline/pdfProcess/PageLabel.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.ririv.quickoutline.pdfProcess;


//https://opensource.adobe.com/dc-acrobat-sdk-docs/standards/pdfstandards/pdf/PDF32000_2008.pdf#page=383
//根据PDF标准
//与iText的PageLabel对应
public record PageLabel(int pageNum, PageLabelNumberingStyle numberingStyle, String labelPrefix, Integer firstPage){

public enum PageLabelNumberingStyle{
/**
* 1, 2, 3, 4...
*/
DECIMAL_ARABIC_NUMERALS,
/**
* I, II, III, IV...
*/
UPPERCASE_ROMAN_NUMERALS,
/**
* i, ii, iii, iv...
*/
LOWERCASE_ROMAN_NUMERALS,
/**
* A, B, C, D...
*/
UPPERCASE_LETTERS,
/**
* a, b, c, d...
*/
LOWERCASE_LETTERS
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.ririv.quickoutline.pdfProcess;

import java.io.IOException;
import java.util.List;

public interface PageLabelSetter<T> {

void setPageLabels(String srcFilePath, String destFilePath, List<PageLabel> labelList) throws IOException;

T mapPageLabelNumberingStyle(PageLabel.PageLabelNumberingStyle numberingStyle);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.ririv.quickoutline.pdfProcess;

public enum PdfViewScaleType {
public enum ViewScaleType {
FIT_TO_WIDTH,
FIT_TO_HEIGHT,
FIT_TO_PAGE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import com.ririv.quickoutline.exception.NoOutlineException;
import com.ririv.quickoutline.model.Bookmark;
import com.ririv.quickoutline.pdfProcess.OutlineProcessor;
import com.ririv.quickoutline.pdfProcess.PdfViewScaleType;
import com.ririv.quickoutline.pdfProcess.ViewScaleType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -25,7 +25,7 @@ public class ItextOutlineProcessor implements OutlineProcessor {
// 如果rootBookmark没有Children,即之前的text为空(当然这种情况已在Controller中被排除)
// list.clear()没有起作用(不知道原因),最终目录没有影响,怀疑原因是没有写入操作。
@Override
public void setContents(Bookmark rootBookmark, String srcFilePath, String destFilePath, PdfViewScaleType scaleType) throws IOException {
public void setContents(Bookmark rootBookmark, String srcFilePath, String destFilePath, ViewScaleType scaleType) throws IOException {
if (checkEncrypted(srcFilePath)) throw new EncryptedPdfException();

PdfDocument pdfDoc = new PdfDocument(new PdfReader(srcFilePath), new PdfWriter(destFilePath));
Expand All @@ -41,7 +41,7 @@ public void setContents(Bookmark rootBookmark, String srcFilePath, String destFi


//合并了上面两个函数
private void bookmarkToOutlines(Bookmark parentBookmark, PdfOutline rootOutline, PdfDocument srcDoc, PdfViewScaleType scaleType) {
private void bookmarkToOutlines(Bookmark parentBookmark, PdfOutline rootOutline, PdfDocument srcDoc, ViewScaleType scaleType) {

//不为根结点时,进行添加操作
if (!parentBookmark.isRoot()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,106 +1,74 @@
package com.ririv.quickoutline.pdfProcess.itextImpl;

import com.itextpdf.io.font.constants.StandardFonts;
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.*;
import com.itextpdf.kernel.pdf.action.PdfAction;
import com.itextpdf.kernel.pdf.annot.PdfAnnotation;
import com.itextpdf.kernel.pdf.annot.PdfTextAnnotation;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.AreaBreak;
import com.itextpdf.layout.element.Link;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.kernel.pdf.PageLabelNumberingStyle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.ririv.quickoutline.pdfProcess.PageLabel;
import com.ririv.quickoutline.pdfProcess.PageLabelSetter;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class ItextPageLabelSetter {


public static final String DEST = "./target/sandbox/objects/page_labels.pdf";
// https://kb.itextpdf.com/itext/page-labels
public class ItextPageLabelSetter implements PageLabelSetter<PageLabelNumberingStyle> {

public static void main(String[] args) throws IOException {
final String SRC = "";
final String DEST = "./target/sandbox/objects/page_labels.pdf";

List<PageLabel> labelList = new ArrayList<>();
labelList.add(new PageLabel(1, PageLabel.PageLabelNumberingStyle.UPPERCASE_LETTERS,null,null));
File file = new File(DEST);
file.getParentFile().mkdirs();
new ItextPageLabelSetter().setPdfLabels(DEST);
new ItextPageLabelSetter().setPageLabels(SRC, DEST, labelList);
}

protected void setPdfLabels(String dest) throws IOException {
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
Document doc = new Document(pdfDoc);

PdfViewerPreferences viewerPreferences = new PdfViewerPreferences();
viewerPreferences.setPrintScaling(PdfViewerPreferences.PdfViewerPreferencesConstants.NONE);
pdfDoc.getCatalog().setPageMode(PdfName.UseThumbs);
pdfDoc.getCatalog().setPageLayout(PdfName.TwoPageLeft);
pdfDoc.getCatalog().setViewerPreferences(viewerPreferences);

doc.add(new Paragraph("Hello World"));
doc.add(new Paragraph("Hello People"));

doc.add(new AreaBreak());
PdfFont font = PdfFontFactory.createFont(StandardFonts.HELVETICA);
public void setPageLabels(String srcFilePath, String destFilePath, List<PageLabel> labelList) throws IOException {
PdfDocument pdfDoc = new PdfDocument(new PdfReader(srcFilePath), new PdfWriter(destFilePath));

// Add the text to the direct content, but not in the right order
PdfCanvas canvas = new PdfCanvas(pdfDoc.getPage(2));
canvas.beginText();
canvas.setFontAndSize(font, 12);
canvas.moveText(88.66f, 788);
canvas.showText("ld");
canvas.moveText(-22f, 0);
canvas.showText("Wor");
canvas.moveText(-15.33f, 0);
canvas.showText("llo");
canvas.moveText(-15.33f, 0);
canvas.showText("He");
canvas.endText();
PdfFormXObject formXObject = new PdfFormXObject(new Rectangle(250, 25));
new PdfCanvas(formXObject, pdfDoc).beginText()
.setFontAndSize(font, 12)
.moveText(0, 7)
.showText("Hello People")
.endText();
canvas.addXObjectAt(formXObject, 36, 763);
for(PageLabel label: labelList){
int pageNum = label.pageNum();
PageLabelNumberingStyle numberingStyle = mapPageLabelNumberingStyle(label.numberingStyle());

pdfDoc.setDefaultPageSize(new PageSize(PageSize.A4).rotate());
doc.add(new AreaBreak());
doc.add(new Paragraph("Hello World"));
String labelPrefix = label.labelPrefix();
Integer firstPage = label.firstPage();

pdfDoc.setDefaultPageSize(new PageSize(842, 595));
doc.add(new AreaBreak());
doc.add(new Paragraph("Hello World"));
if (label.firstPage() ==null){
pdfDoc.getPage(pageNum).setPageLabel(numberingStyle, labelPrefix);
} else {
pdfDoc.getPage(pageNum).setPageLabel(numberingStyle, labelPrefix, firstPage);
}
}

pdfDoc.setDefaultPageSize(PageSize.A4);
doc.add(new AreaBreak());
pdfDoc.getLastPage().setCropBox(new Rectangle(10, 70, 525, 755));
doc.add(new Paragraph("Hello World"));

doc.add(new AreaBreak());
pdfDoc.getLastPage().getPdfObject().put(PdfName.UserUnit, new PdfNumber(5));
doc.add(new Paragraph("Hello World"));

doc.add(new AreaBreak());
pdfDoc.getLastPage().setArtBox(new Rectangle(36, 36, 523, 770));
Paragraph p = new Paragraph("Hello ")
.add(new Link("World", PdfAction.createURI("http://maps.google.com")));
doc.add(p);
PdfAnnotation a = new PdfTextAnnotation(
new Rectangle(36, 755, 30, 30))
.setTitle(new PdfString("Example"))
.setContents("This is a post-it annotation");
pdfDoc.getLastPage().addAnnotation(a);


pdfDoc.getPage(1).setPageLabel(PageLabelNumberingStyle.UPPERCASE_LETTERS, null);
pdfDoc.getPage(3).setPageLabel(PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS, null);
pdfDoc.getPage(4).setPageLabel(PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS, "Custom-", 2);
}

doc.close();
@Override
public PageLabelNumberingStyle mapPageLabelNumberingStyle(PageLabel.PageLabelNumberingStyle numberingStyle) {

switch (numberingStyle) {
case PageLabel.PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS -> {
return PageLabelNumberingStyle.DECIMAL_ARABIC_NUMERALS;
}
case PageLabel.PageLabelNumberingStyle.LOWERCASE_ROMAN_NUMERALS -> {
return PageLabelNumberingStyle.LOWERCASE_ROMAN_NUMERALS;
}
case PageLabel.PageLabelNumberingStyle.UPPERCASE_ROMAN_NUMERALS-> {
return PageLabelNumberingStyle.UPPERCASE_ROMAN_NUMERALS;
}
case PageLabel.PageLabelNumberingStyle.LOWERCASE_LETTERS-> {
return PageLabelNumberingStyle.LOWERCASE_LETTERS;
}
case PageLabel.PageLabelNumberingStyle.UPPERCASE_LETTERS-> {
return PageLabelNumberingStyle.UPPERCASE_LETTERS;
}
case null -> {
return null;
}
}
}

}
18 changes: 18 additions & 0 deletions src/main/java/com/ririv/quickoutline/service/PdfLabelService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.ririv.quickoutline.service;

import com.itextpdf.kernel.pdf.PageLabelNumberingStyle;
import com.ririv.quickoutline.pdfProcess.PageLabel;
import com.ririv.quickoutline.pdfProcess.PageLabelSetter;
import com.ririv.quickoutline.pdfProcess.itextImpl.ItextPageLabelSetter;

import java.io.IOException;
import java.util.List;

public class PdfLabelService {
private final PageLabelSetter<PageLabelNumberingStyle> pageLabelSetter = new ItextPageLabelSetter();

public void setPageLabels(String srcFilePath, String destFilePath, List<PageLabel> labelList) throws IOException{
pageLabelSetter.setPageLabels(srcFilePath, destFilePath, labelList);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
import com.ririv.quickoutline.exception.NoOutlineException;
import com.ririv.quickoutline.model.Bookmark;
import com.ririv.quickoutline.pdfProcess.OutlineProcessor;
import com.ririv.quickoutline.pdfProcess.PdfViewScaleType;
import com.ririv.quickoutline.pdfProcess.ViewScaleType;
import com.ririv.quickoutline.pdfProcess.itextImpl.ItextOutlineProcessor;
import com.ririv.quickoutline.textProcess.TextProcessor;
import com.ririv.quickoutline.textProcess.methods.Method;

import java.io.IOException;


public class PdfService {
public class PdfOutlineService {

private final OutlineProcessor outlineProcessor = new ItextOutlineProcessor();

public void setContents(String text, String srcFilePath, String destFilePath, int offset, Method method, PdfViewScaleType scaleType) throws IOException {
public void setContents(String text, String srcFilePath, String destFilePath, int offset, Method method, ViewScaleType scaleType) throws IOException {
if (srcFilePath.isEmpty()) throw new RuntimeException("PDF路径为空");

Bookmark rootBookmark = convertTextToBookmarkTreeByMethod(text, offset, method);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import java.io.IOException;

public class TocService {
public class PdfTocService {

public String extract(String pdfPath){
try {
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/ririv/quickoutline/view/App.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.ririv.quickoutline.view;//package com.ririv.contents.view;
package com.ririv.quickoutline.view;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
Expand All @@ -14,7 +14,7 @@

public class App extends Application {

// 注意javafx程序架子顺序:main启动程序,加载fxml,fxml加载指定的controller
// 注意javafx程序架子顺序:main启动程序,加载fxmlfxml加载指定的controller
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader();
Expand All @@ -27,7 +27,7 @@ public void start(Stage stage) throws IOException {


// stage.setResizable(false); //不可调整大小
stage.setTitle("QuickOutline - 编辑与添加PDF目录");
stage.setTitle("QuickOutline - 编辑与添加PDF书签/目录");
stage.getIcons().add(new Image(Objects.requireNonNull(getClass().getResourceAsStream("icon/icon.png"))));
stage.setScene(scene);
stage.show();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.ririv.quickoutline.view;

import com.ririv.quickoutline.service.TocService;
import com.ririv.quickoutline.service.PdfTocService;
import com.ririv.quickoutline.view.controls.Message;
import com.ririv.quickoutline.view.controls.Switch;
import javafx.beans.property.BooleanProperty;
Expand Down Expand Up @@ -57,7 +57,7 @@ public GetContentsPopupController(MainController mainController) {
}

public void initialize() {
TocService tocService = new TocService();
PdfTocService pdfTocService = new PdfTocService();


autoRecognize.bind(autoRecognizeSwitch.valueProperty());
Expand Down Expand Up @@ -104,12 +104,12 @@ public void initialize() {

String contents;
if (autoRecognize.get()) {
contents = tocService.extract(filepath.get());
contents = pdfTocService.extract(filepath.get());
} else {
if (startTF.getText().isEmpty() || endTF.getText().isEmpty()) {
mainController.messageManager.showMessage("请输入起始页码和结束页码", Message.MessageType.WARNING);
}
contents = tocService.extract(filepath.get(), Integer.parseInt(startTF.getText()), Integer.parseInt(endTF.getText()));
contents = pdfTocService.extract(filepath.get(), Integer.parseInt(startTF.getText()), Integer.parseInt(endTF.getText()));
}
this.mainController.textTabViewController.contentsTextArea.setText(contents);
});
Expand Down
Loading

0 comments on commit e4424b5

Please sign in to comment.