|
|
@@ -720,12 +720,45 @@ export async function GeneratePDF(ctx) {
|
|
720
|
720
|
const articleEndY = doc.y;
|
|
721
|
721
|
const wordListEndY = doc.y; // 假设单词列表的Y坐标
|
|
722
|
722
|
const maxY = Math.max(articleEndY, wordListEndY);
|
|
|
723
|
+
|
|
|
724
|
+ // 检查内容是否过长,需要分页
|
|
|
725
|
+ const pageHeight = doc.page.height;
|
|
|
726
|
+ const availableHeight = pageHeight - pixelToPt(400); // 预留底部空间
|
|
|
727
|
+ const needsNewPage = articleEndY > availableHeight;
|
|
|
728
|
+
|
|
723
|
729
|
if (doc && typeof doc.line === 'function') {
|
|
724
|
730
|
doc.line(20, maxY, 200, maxY);
|
|
725
|
731
|
}
|
|
726
|
|
- doc.rect(pixelToPt(120), articleEndY + pixelToPt(41),
|
|
727
|
|
- pixelToPt(1860), pixelToPt(10))
|
|
728
|
|
- .fill('black');
|
|
|
732
|
+
|
|
|
733
|
+ // 如果内容过长,则创建新页面
|
|
|
734
|
+ if (needsNewPage) {
|
|
|
735
|
+ // 在第一页底部添加提示
|
|
|
736
|
+ doc.font('Helvetica')
|
|
|
737
|
+ .fontSize(pixelToPt(24))
|
|
|
738
|
+ .text("(Continued on next page...)",
|
|
|
739
|
+ pixelToPt(740), pageHeight - pixelToPt(100), {
|
|
|
740
|
+ align: 'center'
|
|
|
741
|
+ });
|
|
|
742
|
+
|
|
|
743
|
+ // 添加新页面
|
|
|
744
|
+ doc.addPage();
|
|
|
745
|
+
|
|
|
746
|
+ // 在新页面顶部添加标题
|
|
|
747
|
+ doc.font(selectFont(articleStyle))
|
|
|
748
|
+ .fontSize(pixelToPt(36))
|
|
|
749
|
+ .text(articleStyle + " (Continued)",
|
|
|
750
|
+ pixelToPt(120), pixelToPt(50));
|
|
|
751
|
+
|
|
|
752
|
+ // 在新页面添加黑线
|
|
|
753
|
+ doc.rect(pixelToPt(120), pixelToPt(100),
|
|
|
754
|
+ pixelToPt(1860), pixelToPt(10))
|
|
|
755
|
+ .fill('black');
|
|
|
756
|
+ } else {
|
|
|
757
|
+ // 如果不需要分页,正常添加黑线
|
|
|
758
|
+ doc.rect(pixelToPt(120), articleEndY + pixelToPt(41),
|
|
|
759
|
+ pixelToPt(1860), pixelToPt(10))
|
|
|
760
|
+ .fill('black');
|
|
|
761
|
+ }
|
|
729
|
762
|
|
|
730
|
763
|
// 8-13. 问题和答案
|
|
731
|
764
|
if (questions.length > 0) {
|
|
|
@@ -744,13 +777,20 @@ export async function GeneratePDF(ctx) {
|
|
744
|
777
|
column2: 0, // 用于跟踪第二列(问题3)的最后位置
|
|
745
|
778
|
};
|
|
746
|
779
|
|
|
|
780
|
+ // 确定问题的起始Y坐标
|
|
|
781
|
+ // 如果内容过长需要分页,则在新页面上从固定位置开始
|
|
|
782
|
+ // 否则在文章内容下方开始
|
|
|
783
|
+ const questionsStartY = needsNewPage ?
|
|
|
784
|
+ pixelToPt(150) : // 新页面上的起始位置
|
|
|
785
|
+ articleEndY + pixelToPt(130); // 原页面上的起始位置
|
|
|
786
|
+
|
|
747
|
787
|
// 首先渲染问题1、3、5(第一行问题)
|
|
748
|
788
|
const firstRowQuestions = [0, 2, 4]; // 问题1、3、5的索引
|
|
749
|
789
|
|
|
750
|
790
|
for (const i of firstRowQuestions) {
|
|
751
|
791
|
if (i < questions.length && questions[i]) {
|
|
752
|
792
|
const currentX = questionXPositions[i];
|
|
753
|
|
- const currentY = articleEndY + pixelToPt(130); // 所有第一行问题的起始Y坐标相同
|
|
|
793
|
+ const currentY = questionsStartY; // 使用计算出的起始Y坐标
|
|
754
|
794
|
|
|
755
|
795
|
questions[i].QuestionEnglish = questions[i].QuestionEnglish.replace(/(^|[,.]\s+)'([^']+)'/g, '$1"$2"');
|
|
756
|
796
|
|
|
|
@@ -923,10 +963,11 @@ export async function GeneratePDF(ctx) {
|
|
923
|
963
|
});
|
|
924
|
964
|
}
|
|
925
|
965
|
|
|
926
|
|
- // 问题5保持原位置不变
|
|
|
966
|
+ // 问题5
|
|
927
|
967
|
if (questions.length > 4 && questions[4]) {
|
|
928
|
968
|
const currentX = questionXPositions[4];
|
|
929
|
|
- const currentY = articleEndY + pixelToPt(130);
|
|
|
969
|
+ // 如果分页,问题5的Y坐标与问题1和3相同
|
|
|
970
|
+ const currentY = questionsStartY;
|
|
930
|
971
|
|
|
931
|
972
|
doc.font('Helvetica-Bold')
|
|
932
|
973
|
.fontSize(pixelToPt(36))
|
|
|
@@ -978,10 +1019,11 @@ export async function GeneratePDF(ctx) {
|
|
978
|
1019
|
}
|
|
979
|
1020
|
|
|
980
|
1021
|
// 14. 虚线
|
|
981
|
|
- const lastContentY = doc.page.height - pixelToPt(190);
|
|
982
|
|
- // doc.rect(pixelToPt(120), lastContentY,
|
|
983
|
|
- // pixelToPt(1630), pixelToPt(10))
|
|
984
|
|
- // .fill('#D2D2D2');
|
|
|
1022
|
+ // 计算虚线的位置 - 如果是分页,则在新页面上绘制
|
|
|
1023
|
+ const lastContentY = needsNewPage ?
|
|
|
1024
|
+ doc.page.height - pixelToPt(190) : // 新页面上的位置
|
|
|
1025
|
+ doc.page.height - pixelToPt(190); // 原页面上的位置
|
|
|
1026
|
+
|
|
985
|
1027
|
doc.strokeColor('#D2D2D2')
|
|
986
|
1028
|
.dash(pixelToPt(20), { space: pixelToPt(28) }) // 设置虚线样式:宽20像素,间隔20像素
|
|
987
|
1029
|
.lineWidth(pixelToPt(10)) // 线高10像素
|