Skip to content

Commit 7f96aec

Browse files
committed
feat: 增加 document 属性弹窗
1 parent 550c547 commit 7f96aec

3 files changed

Lines changed: 228 additions & 4 deletions

File tree

src/components/BootstrapBlazor.PdfReader/PdfReader.razor

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@
7474
}
7575
@if (ShowTwoPagesOneView || ShowPresentationMode)
7676
{
77-
<Divider></Divider>
77+
<div class="divider">
78+
<div class="divider-mask"></div>
79+
</div>
7880
}
7981
<div class="dropdown-item dropdown-item-doc">
8082
<i class="@_dropdownItemDefaultIcon"></i>
@@ -96,4 +98,75 @@
9698
</div>
9799
</div>
98100
</div>
101+
<div class="bb-view-pdf-info">
102+
<div class="bb-view-pdf-backdrop"></div>
103+
<div class="bb-view-pdf-dialog">
104+
<div class="bb-view-pdf-dialog-title mb-3">Document properties</div>
105+
<div class="bb-view-pdf-dialog-item">
106+
<div class="bb-view-pdf-dialog-label">File name:</div>
107+
<div class="bb-view-pdf-dialog-filename"></div>
108+
</div>
109+
<div class="bb-view-pdf-dialog-item">
110+
<div class="bb-view-pdf-dialog-label">File size:</div>
111+
<div class="bb-view-pdf-dialog-filesize"></div>
112+
</div>
113+
<div class="divider">
114+
<div class="divider-mask"></div>
115+
</div>
116+
<div class="bb-view-pdf-dialog-item">
117+
<div class="bb-view-pdf-dialog-label">Title:</div>
118+
<div class="bb-view-pdf-dialog-title"></div>
119+
</div>
120+
<div class="bb-view-pdf-dialog-item">
121+
<div class="bb-view-pdf-dialog-label">Author:</div>
122+
<div class="bb-view-pdf-dialog-author"></div>
123+
</div>
124+
<div class="bb-view-pdf-dialog-item">
125+
<div class="bb-view-pdf-dialog-label">Subject:</div>
126+
<div class="bb-view-pdf-dialog-subject"></div>
127+
</div>
128+
<div class="bb-view-pdf-dialog-item">
129+
<div class="bb-view-pdf-dialog-label">Keywords:</div>
130+
<div class="bb-view-pdf-dialog-keywords"></div>
131+
</div>
132+
<div class="bb-view-pdf-dialog-item">
133+
<div class="bb-view-pdf-dialog-label">Created:</div>
134+
<div class="bb-view-pdf-dialog-created"></div>
135+
</div>
136+
<div class="bb-view-pdf-dialog-item">
137+
<div class="bb-view-pdf-dialog-label">Modified:</div>
138+
<div class="bb-view-pdf-dialog-modified"></div>
139+
</div>
140+
<div class="bb-view-pdf-dialog-item">
141+
<div class="bb-view-pdf-dialog-label">Application:</div>
142+
<div class="bb-view-pdf-dialog-application"></div>
143+
</div>
144+
<div class="divider">
145+
<div class="divider-mask"></div>
146+
</div>
147+
<div class="bb-view-pdf-dialog-item">
148+
<div class="bb-view-pdf-dialog-label">PDF producer:</div>
149+
<div class="bb-view-pdf-dialog-producer"></div>
150+
</div>
151+
<div class="bb-view-pdf-dialog-item">
152+
<div class="bb-view-pdf-dialog-label">PDF version:</div>
153+
<div class="bb-view-pdf-dialog-version"></div>
154+
</div>
155+
<div class="bb-view-pdf-dialog-item">
156+
<div class="bb-view-pdf-dialog-label">Page count:</div>
157+
<div class="bb-view-pdf-dialog-count"></div>
158+
</div>
159+
<div class="bb-view-pdf-dialog-item">
160+
<div class="bb-view-pdf-dialog-label">Page size:</div>
161+
<div class="bb-view-pdf-dialog-size"></div>
162+
</div>
163+
<div class="divider">
164+
<div class="divider-mask"></div>
165+
</div>
166+
<div class="bb-view-pdf-dialog-item">
167+
<div class="bb-view-pdf-dialog-label">Fast web view:</div>
168+
<div class="bb-view-pdf-dialog-webview">No</div>
169+
</div>
170+
</div>
171+
</div>
99172
</div>

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.css

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,43 @@
209209
background-color: #000;
210210
inset: 0;
211211
}
212+
213+
.bb-view-pdf-info {
214+
position: absolute;
215+
inset: 0;
216+
display: flex;
217+
align-items: center;
218+
justify-content: center;
219+
220+
}
221+
222+
.bb-view-pdf-backdrop {
223+
position: absolute;
224+
inset: 0;
225+
background-color: #000;
226+
opacity: 0.6;
227+
z-index: 1;
228+
}
229+
230+
.bb-view-pdf-dialog {
231+
background-color: #fff;
232+
padding: 1rem;
233+
z-index: 5;
234+
border-radius: var(--bs-border-radius);
235+
}
236+
237+
.bb-view-pdf-dialog-item {
238+
display: flex;
239+
flex-wrap: nowrap;
240+
width: 344px;
241+
}
242+
243+
.bb-view-pdf-dialog-item:not(:last-child) {
244+
margin-block-start: .5rem;
245+
}
246+
247+
.bb-view-pdf-dialog-label {
248+
width: 108px;
249+
white-space: nowrap;
250+
overflow: hidden;
251+
}

src/components/BootstrapBlazor.PdfReader/PdfReader.razor.js

Lines changed: 114 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,120 @@ const loadPdf = async (el, invoke, options) => {
101101
const pdfDocument = await loadingTask.promise;
102102
pdfViewer.setDocument(pdfDocument);
103103

104+
pdfDocument.getMetadata().then(metadata => {
105+
loadMetadata(el, pdfViewer, metadata);
106+
});
107+
104108
return pdfViewer;
105109
}
106110

111+
const loadMetadata = (el, pdfViewer, metadata) => {
112+
console.log(metadata);
113+
114+
const filename = el.querySelector('.bb-view-pdf-dialog-filename');
115+
const docTitle = el.querySelector('.bb-view-subject');
116+
filename.textContent = docTitle.textContent;
117+
118+
const filesize = el.querySelector('.bb-view-pdf-dialog-filesize');
119+
filesize.textContent = getFilesize(metadata);
120+
121+
const title = el.querySelector('.bb-view-pdf-dialog-title');
122+
const author = el.querySelector('.bb-view-pdf-dialog-author');
123+
const subject = el.querySelector('.bb-view-pdf-dialog-subject');
124+
const keywords = el.querySelector('.bb-view-pdf-dialog-keywords');
125+
const created = el.querySelector('.bb-view-pdf-dialog-created');
126+
created.textContent = parsePdfDate(metadata.info.CreationDate)?.toLocaleString();
127+
128+
const modified = el.querySelector('.bb-view-pdf-dialog-modified');
129+
130+
const application = el.querySelector('.bb-view-pdf-dialog-application');
131+
application.textContent = metadata.info.Creator;
132+
133+
const producer = el.querySelector('.bb-view-pdf-dialog-producer');
134+
producer.textContent = metadata.info.Producer;
135+
136+
const version = el.querySelector('.bb-view-pdf-dialog-version');
137+
version.textContent = metadata.info.PDFFormatVersion;
138+
139+
const count = el.querySelector('.bb-view-pdf-dialog-count');
140+
count.textContent = pdfViewer.pagesCount;
141+
142+
const size = el.querySelector('.bb-view-pdf-dialog-size');
143+
pdfViewer.pdfDocument.getPage(pdfViewer.currentPageNumber).then(page => {
144+
const viewport = page.getViewport({scale: 1});
145+
size.textContent = `${(viewport.width / 72).toFixed(2)} * ${(viewport.height / 72).toFixed(2)} in (portrait)`;
146+
});
147+
148+
const webview = el.querySelector('.bb-view-pdf-dialog-webview');
149+
}
150+
151+
function parsePdfDate(pdfDateString) {
152+
if (!pdfDateString || typeof pdfDateString !== 'string') {
153+
return null;
154+
}
155+
156+
let dateStr = pdfDateString.startsWith('D:') ? pdfDateString.substring(2) : pdfDateString;
157+
158+
const pdfDateRegex = /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})([Zz+-])(\d{2})'?(\d{2})'?$/;
159+
const match = dateStr.match(pdfDateRegex);
160+
161+
if (!match) {
162+
return null;
163+
}
164+
165+
const [, year, month, day, hours, minutes, seconds, timezoneSign, timezoneHours, timezoneMinutes ] = match;
166+
167+
const date = new Date(
168+
parseInt(year),
169+
parseInt(month) - 1,
170+
parseInt(day),
171+
parseInt(hours),
172+
parseInt(minutes),
173+
parseInt(seconds)
174+
);
175+
176+
if (timezoneSign === 'Z' || timezoneSign === 'z') {
177+
const utcTime = Date.UTC(
178+
parseInt(year),
179+
parseInt(month) - 1,
180+
parseInt(day),
181+
parseInt(hours),
182+
parseInt(minutes),
183+
parseInt(seconds)
184+
);
185+
date.setTime(utcTime);
186+
}
187+
else if (timezoneSign === '+' || timezoneSign === '-') {
188+
const offsetHours = parseInt(timezoneHours);
189+
const offsetMinutes = parseInt(timezoneMinutes || 0);
190+
const totalOffsetMinutes = offsetHours * 60 + offsetMinutes;
191+
192+
if (timezoneSign === '+') {
193+
date.setMinutes(date.getMinutes() - totalOffsetMinutes);
194+
}
195+
else {
196+
date.setMinutes(date.getMinutes() + totalOffsetMinutes);
197+
}
198+
}
199+
return date;
200+
}
201+
202+
const getFilesize = metadata => {
203+
const length = metadata.contentLength;
204+
if (length < 1024) {
205+
return `${Math.round(length)}B`;
206+
}
207+
else if (length < 1024 * 1024) {
208+
return `${Math.round(length / 1024)}KB`;
209+
}
210+
else if (length < 1024 * 1024 * 1024) {
211+
return `${length / 1024 / 1024}MB`;
212+
}
213+
else if (length < 1024 * 1024 * 1024 * 1024) {
214+
return `${length / 1024 / 1024 / 1024}GB`;
215+
}
216+
}
217+
107218
const setObserver = el => {
108219
const observer = new ResizeObserver(entries => {
109220
relayoutToolbar(el);
@@ -402,7 +513,7 @@ const updateScaleValue = (el, value) => {
402513
const scaleEl = el.querySelector(".bb-view-scale-input");
403514

404515
const scale = value * 100;
405-
scaleEl.value = `${Math.round(scale, 0)}%`;
516+
scaleEl.value = `${Math.round(scale)}%`;
406517

407518
if (scale === 25) {
408519
minus.classList.add("disabled");
@@ -422,7 +533,7 @@ const updateScale = (pdfViewer, button, rate) => {
422533
}
423534

424535
const scale = pdfViewer.currentScale;
425-
const current = Math.round(parseFloat(scale * 100), 0);
536+
const current = Math.round(parseFloat(scale * 100));
426537
const step = [25, 33, 50, 67, 75, 80, 90, 100, 110, 125, 150, 175, 200, 250, 300, 400, 500];
427538
const findValues = step.filter(s => rate > 0 ? current < s : current > s);
428539
if (findValues.length === 0) {
@@ -462,7 +573,7 @@ const printPdf = url => {
462573
}
463574

464575
iframe = document.createElement("iframe");
465-
iframe.classList = "bb-view-print-iframe";
576+
iframe.classList.add("bb-view-print-iframe");
466577
iframe.style.position = "fixed";
467578
iframe.style.right = "100%";
468579
iframe.style.bottom = "100%";

0 commit comments

Comments
 (0)